2026-05-16 15:47:07 +08:00
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import { ref, computed } from 'vue'
|
|
|
|
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
|
|
|
|
import { getToolboxItem } from '@/config/toolboxRegistry'
|
|
|
|
|
|
import { postToolboxQuery } from '@/api/toolbox'
|
|
|
|
|
|
|
|
|
|
|
|
definePage({
|
|
|
|
|
|
style: {
|
|
|
|
|
|
navigationBarTitleText: '工具查询',
|
|
|
|
|
|
navigationStyle: 'default',
|
|
|
|
|
|
navigationBarBackgroundColor: '#ffffff',
|
|
|
|
|
|
navigationBarTextStyle: 'black',
|
|
|
|
|
|
enablePullDownRefresh: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const toolKey = ref('')
|
|
|
|
|
|
const tool = ref<ReturnType<typeof getToolboxItem>>(null)
|
|
|
|
|
|
|
|
|
|
|
|
const form = ref<Record<string, string>>({})
|
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
|
const result = ref<Record<string, any> | null>(null)
|
|
|
|
|
|
const error = ref('')
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
// 游戏相关状态
|
|
|
|
|
|
const gameOptions = ref<Array<{ label: string; value: string; isCorrect: boolean }>>([])
|
|
|
|
|
|
const selectedOption = ref<string | null>(null)
|
|
|
|
|
|
const answered = ref(false)
|
|
|
|
|
|
const answeredCorrect = ref(false)
|
|
|
|
|
|
const systemIdiom = ref('') // 系统给出的成语
|
|
|
|
|
|
const chainGameStep = ref(0) // 接龙游戏步骤:0=初始,1=用户输入
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
// 选择框相关状态
|
|
|
|
|
|
const popup = ref<any>(null)
|
|
|
|
|
|
const currentField = ref<any>(null)
|
|
|
|
|
|
const pickerValue = ref([0])
|
|
|
|
|
|
const indicatorStyle = `'height: 50px'`
|
|
|
|
|
|
|
|
|
|
|
|
onLoad((query) => {
|
|
|
|
|
|
const key = (query?.key as string) || ''
|
|
|
|
|
|
toolKey.value = key
|
|
|
|
|
|
tool.value = getToolboxItem(key)
|
2026-05-20 14:48:07 +08:00
|
|
|
|
console.log('工具配置:', tool.value)
|
2026-05-16 15:47:07 +08:00
|
|
|
|
if (!tool.value) {
|
|
|
|
|
|
error.value = '未找到该工具'
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
uni.setNavigationBarTitle({ title: tool.value.name })
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化表单默认值
|
|
|
|
|
|
if (tool.value.fields) {
|
|
|
|
|
|
tool.value.fields.forEach(field => {
|
2026-05-20 14:48:07 +08:00
|
|
|
|
// 设置默认值
|
2026-05-16 15:47:07 +08:00
|
|
|
|
if (field.default !== undefined && !form.value[field.key]) {
|
|
|
|
|
|
form.value[field.key] = field.default
|
|
|
|
|
|
}
|
2026-05-20 14:48:07 +08:00
|
|
|
|
// 对于 select 类型,即使没有值也设置默认值
|
|
|
|
|
|
if (field.type === 'select' && !form.value[field.key] && field.default !== undefined) {
|
|
|
|
|
|
form.value[field.key] = field.default
|
|
|
|
|
|
}
|
|
|
|
|
|
// 如果是日期字段且没有默认值,设置为今天
|
|
|
|
|
|
if (field.type === 'date' && !form.value[field.key]) {
|
|
|
|
|
|
const today = new Date()
|
|
|
|
|
|
const year = today.getFullYear()
|
|
|
|
|
|
const month = String(today.getMonth() + 1).padStart(2, '0')
|
|
|
|
|
|
const day = String(today.getDate()).padStart(2, '0')
|
|
|
|
|
|
form.value[field.key] = `${year}-${month}-${day}`
|
|
|
|
|
|
}
|
2026-05-16 15:47:07 +08:00
|
|
|
|
})
|
2026-05-20 14:48:07 +08:00
|
|
|
|
console.log('初始化后的表单:', JSON.stringify(form.value))
|
2026-05-16 15:47:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果工具标记了自动查询或不需要输入参数,打开即查
|
|
|
|
|
|
if (tool.value.autoQuery || tool.value.fields.length === 0) {
|
|
|
|
|
|
handleQuery()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 获取选择框当前选中项的索引
|
|
|
|
|
|
function getSelectIndex(field, value) {
|
|
|
|
|
|
if (!field.options || !Array.isArray(field.options)) {
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
const defaultValue = field.options[0]?.value || ''
|
|
|
|
|
|
const targetValue = value || defaultValue
|
|
|
|
|
|
return field.options.findIndex(opt => opt.value === targetValue)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取选择框当前选中项的标签
|
|
|
|
|
|
function getSelectedLabel(field, value) {
|
|
|
|
|
|
if (!field.options || !Array.isArray(field.options) || !value) {
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
const option = field.options.find(opt => opt.value === value)
|
|
|
|
|
|
return option ? option.label : null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
// 判断字段是否可见
|
|
|
|
|
|
function isFieldVisible(field, formValue) {
|
|
|
|
|
|
if (!tool.value?.fieldVisibility || !field.key) {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
const visibilityFn = tool.value.fieldVisibility[field.key]
|
|
|
|
|
|
if (visibilityFn && typeof visibilityFn === 'function') {
|
|
|
|
|
|
return visibilityFn(formValue)
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取动态placeholder
|
|
|
|
|
|
function getFieldPlaceholder(field) {
|
|
|
|
|
|
if (!tool.value?.fieldPlaceholder || !field.key) {
|
|
|
|
|
|
return field.placeholder || ''
|
|
|
|
|
|
}
|
|
|
|
|
|
const placeholderFn = tool.value.fieldPlaceholder[field.key]
|
|
|
|
|
|
if (placeholderFn && typeof placeholderFn === 'function') {
|
|
|
|
|
|
return placeholderFn(form.value)
|
|
|
|
|
|
}
|
|
|
|
|
|
return field.placeholder || ''
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理单选按钮切换
|
|
|
|
|
|
function handleRadioChange(fieldKey: string, value: any) {
|
|
|
|
|
|
form.value[fieldKey] = value
|
|
|
|
|
|
// 清空依赖该字段的其他字段值
|
|
|
|
|
|
if (tool.value?.fieldVisibility) {
|
|
|
|
|
|
Object.keys(tool.value.fieldVisibility).forEach(key => {
|
|
|
|
|
|
const visibilityFn = tool.value.fieldVisibility[key]
|
|
|
|
|
|
if (visibilityFn && !visibilityFn(form.value)) {
|
|
|
|
|
|
form.value[key] = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
// 清空word字段的值
|
|
|
|
|
|
if (fieldKey === 'type') {
|
|
|
|
|
|
form.value['word'] = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取显示值(支持 transform)
|
|
|
|
|
|
function getDisplayValue(key: string, value: any) {
|
|
|
|
|
|
if (!tool.value?.resultLabels)
|
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
const labelOrObj = tool.value.resultLabels[key]
|
|
|
|
|
|
if (typeof labelOrObj === 'object' && labelOrObj !== null && labelOrObj.transform) {
|
|
|
|
|
|
return labelOrObj.transform(value)
|
|
|
|
|
|
}
|
|
|
|
|
|
return value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理输入框输入,自动截断
|
|
|
|
|
|
function handleInput(fieldKey: string, value: string) {
|
|
|
|
|
|
form.value[fieldKey] = value
|
|
|
|
|
|
// 如果有maxlength限制,自动截断
|
|
|
|
|
|
const field = tool.value?.fields?.find(f => f.key === fieldKey)
|
|
|
|
|
|
if (field?.maxlength && value.length > field.maxlength) {
|
|
|
|
|
|
form.value[fieldKey] = value.substring(0, field.maxlength)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
// 显示自定义选择器
|
|
|
|
|
|
function showPicker(field) {
|
|
|
|
|
|
currentField.value = field
|
|
|
|
|
|
const currentValue = form.value[field.key] || field.options[0]?.value || ''
|
|
|
|
|
|
const index = field.options.findIndex(opt => opt.value === currentValue)
|
|
|
|
|
|
pickerValue.value = [index]
|
|
|
|
|
|
popup.value.open()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭选择器
|
|
|
|
|
|
function closePicker() {
|
|
|
|
|
|
popup.value.close()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确认选择
|
|
|
|
|
|
function confirmPicker() {
|
|
|
|
|
|
if (currentField.value) {
|
|
|
|
|
|
const index = pickerValue.value[0]
|
|
|
|
|
|
form.value[currentField.value.key] = currentField.value.options[index].value
|
|
|
|
|
|
closePicker()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 选择器变化处理
|
|
|
|
|
|
function onPickerChange(e) {
|
|
|
|
|
|
pickerValue.value = e.detail.value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function handleQuery() {
|
|
|
|
|
|
if (!tool.value)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
error.value = ''
|
2026-05-20 14:48:07 +08:00
|
|
|
|
answered.value = false
|
|
|
|
|
|
|
|
|
|
|
|
// 成语接龙特殊处理
|
|
|
|
|
|
if (toolKey.value === 'chengyujielong') {
|
|
|
|
|
|
if (!form.value.word) {
|
|
|
|
|
|
error.value = '请输入成语'
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await postToolboxQuery(toolKey.value, {
|
|
|
|
|
|
word: form.value.word,
|
|
|
|
|
|
userid: '1212' // 固定用户ID
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (res.code === 200 && res.data?.result) {
|
|
|
|
|
|
result.value = res.data.result
|
|
|
|
|
|
answered.value = true // 标记已回答
|
|
|
|
|
|
|
|
|
|
|
|
// 如果接龙成功,保存系统返回的成语
|
|
|
|
|
|
if (res.data.result.word) {
|
|
|
|
|
|
systemIdiom.value = res.data.result.word
|
|
|
|
|
|
chainGameStep.value = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
error.value = res.msg || '接龙失败'
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
error.value = '网络错误,请稍后重试'
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
result.value = null
|
|
|
|
|
|
revealedKeys.value = new Set()
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
// 调试:打印表单值
|
|
|
|
|
|
console.log('提交的表单数据:', JSON.stringify(form.value))
|
|
|
|
|
|
console.log('验证结果:', tool.value.validate(form.value))
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
if (!tool.value.validate(form.value)) {
|
|
|
|
|
|
error.value = tool.value.validateMsg
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await postToolboxQuery(toolKey.value, form.value)
|
|
|
|
|
|
if (res.code === 200 && res.data?.result) {
|
|
|
|
|
|
result.value = res.data.result
|
2026-05-20 14:48:07 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果是游戏类工具
|
|
|
|
|
|
if (tool.value?.isGame) {
|
|
|
|
|
|
// 成语填字和诗词填空:准备选项
|
|
|
|
|
|
if (toolKey.value === 'idiom-quiz' || toolKey.value === 'poem-fill') {
|
|
|
|
|
|
prepareGameOptions()
|
|
|
|
|
|
}
|
|
|
|
|
|
// 成语接龙:记录系统返回的成语
|
|
|
|
|
|
if (toolKey.value === 'chengyujielong') {
|
|
|
|
|
|
if (result.value?.word) {
|
|
|
|
|
|
systemIdiom.value = result.value.word
|
|
|
|
|
|
chainGameStep.value = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-16 15:47:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
error.value = res.msg || '查询失败'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch {
|
|
|
|
|
|
error.value = '网络错误,请稍后重试'
|
|
|
|
|
|
}
|
|
|
|
|
|
finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const resultEntries = computed(() => {
|
|
|
|
|
|
if (!result.value || !tool.value?.resultLabels)
|
|
|
|
|
|
return []
|
|
|
|
|
|
return Object.entries(tool.value.resultLabels)
|
|
|
|
|
|
.filter(([key]) => result.value![key] !== undefined)
|
|
|
|
|
|
.map(([key, labelOrObj]) => {
|
|
|
|
|
|
const val = result.value![key]
|
|
|
|
|
|
const display = val === '' || val === null ? '无' : val
|
|
|
|
|
|
if (typeof labelOrObj === 'object' && labelOrObj !== null) {
|
|
|
|
|
|
return { key, label: labelOrObj.label, hidden: !!labelOrObj.hidden, value: display }
|
|
|
|
|
|
}
|
|
|
|
|
|
return { key, label: labelOrObj, hidden: false, value: display }
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const revealedKeys = ref<Set<string>>(new Set())
|
|
|
|
|
|
|
|
|
|
|
|
function toggleReveal(key: string) {
|
|
|
|
|
|
if (revealedKeys.value.has(key)) {
|
|
|
|
|
|
revealedKeys.value.delete(key)
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
revealedKeys.value.add(key)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const resultList = computed(() => {
|
|
|
|
|
|
if (!result.value || tool.value?.resultType !== 'list')
|
|
|
|
|
|
return []
|
|
|
|
|
|
const list = result.value.list
|
|
|
|
|
|
if (!Array.isArray(list))
|
|
|
|
|
|
return []
|
|
|
|
|
|
return list
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-05-18 13:54:57 +08:00
|
|
|
|
const subResultList = computed(() => {
|
|
|
|
|
|
if (!result.value || !tool.value?.subResultKey || !tool.value?.subResultLabels)
|
|
|
|
|
|
return []
|
|
|
|
|
|
const sub = result.value[tool.value.subResultKey]
|
|
|
|
|
|
if (!Array.isArray(sub))
|
|
|
|
|
|
return []
|
|
|
|
|
|
return sub
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const subResultLabelEntries = computed(() => {
|
|
|
|
|
|
if (!tool.value?.subResultLabels)
|
|
|
|
|
|
return []
|
|
|
|
|
|
return Object.entries(tool.value.subResultLabels)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
const listLabelEntries = computed(() => {
|
|
|
|
|
|
if (!tool.value?.resultLabels)
|
|
|
|
|
|
return []
|
|
|
|
|
|
return Object.entries(tool.value.resultLabels)
|
|
|
|
|
|
})
|
2026-05-20 14:48:07 +08:00
|
|
|
|
|
|
|
|
|
|
// 游戏工具:准备选项(打乱顺序)
|
|
|
|
|
|
const prepareGameOptions = () => {
|
|
|
|
|
|
if (!result.value || !result.value.correct)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
const correct = result.value.correct
|
|
|
|
|
|
const options = [
|
|
|
|
|
|
{ label: correct, value: correct, isCorrect: true },
|
|
|
|
|
|
{ label: result.value.wrong_a || '', value: result.value.wrong_a || '', isCorrect: false },
|
|
|
|
|
|
{ label: result.value.wrong_b || '', value: result.value.wrong_b || '', isCorrect: false },
|
|
|
|
|
|
{ label: result.value.wrong_c || '', value: result.value.wrong_c || '', isCorrect: false },
|
|
|
|
|
|
].filter(opt => opt.label) // 过滤空值
|
|
|
|
|
|
|
|
|
|
|
|
// 打乱顺序
|
|
|
|
|
|
for (let i = options.length - 1; i > 0; i--) {
|
|
|
|
|
|
const j = Math.floor(Math.random() * (i + 1))
|
|
|
|
|
|
;[options[i], options[j]] = [options[j], options[i]]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gameOptions.value = options
|
|
|
|
|
|
selectedOption.value = null
|
|
|
|
|
|
answered.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 点击选项
|
|
|
|
|
|
function handleOptionClick(option: { label: string; value: string; isCorrect: boolean }) {
|
|
|
|
|
|
if (answered.value)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
selectedOption.value = option.value
|
|
|
|
|
|
answered.value = true
|
|
|
|
|
|
answeredCorrect.value = option.isCorrect
|
|
|
|
|
|
|
|
|
|
|
|
// 如果答对了,显示完整答案和解释
|
|
|
|
|
|
if (option.isCorrect) {
|
|
|
|
|
|
revealedKeys.value.add('full')
|
|
|
|
|
|
revealedKeys.value.add('explan')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 快速填入:将系统接龙的成语填入输入框
|
|
|
|
|
|
function handleQuickFill() {
|
|
|
|
|
|
if (result.value?.word) {
|
|
|
|
|
|
form.value.word = result.value.word
|
|
|
|
|
|
systemIdiom.value = result.value.word
|
|
|
|
|
|
// 清空之前的结果
|
|
|
|
|
|
result.value = null
|
|
|
|
|
|
answered.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 重新开始(再来一题)
|
|
|
|
|
|
function handleRestart() {
|
|
|
|
|
|
if (toolKey.value === 'chengyujielong') {
|
|
|
|
|
|
// 成语接龙:清空表单,重新开局
|
|
|
|
|
|
form.value.word = ''
|
|
|
|
|
|
systemIdiom.value = ''
|
|
|
|
|
|
chainGameStep.value = 0
|
|
|
|
|
|
answered.value = false
|
|
|
|
|
|
result.value = null
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
handleQuery()
|
|
|
|
|
|
}
|
2026-05-16 15:47:07 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<view class="page-root">
|
|
|
|
|
|
<scroll-view scroll-y class="scrollarea">
|
|
|
|
|
|
<view class="page">
|
|
|
|
|
|
<view v-if="tool" class="card">
|
|
|
|
|
|
<view class="card-desc">
|
|
|
|
|
|
<text class="desc-text">{{ tool.desc }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 动态表单 -->
|
|
|
|
|
|
<view class="form-area">
|
|
|
|
|
|
<view v-for="field in tool.fields" :key="field.key" class="field">
|
2026-05-20 14:48:07 +08:00
|
|
|
|
<!-- 检查字段是否可见 -->
|
|
|
|
|
|
<template v-if="isFieldVisible(field, form)">
|
|
|
|
|
|
<text class="field-label">{{ field.label }}</text>
|
2026-05-16 15:47:07 +08:00
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
<!-- 按钮切换 (Radio) -->
|
|
|
|
|
|
<view v-if="field.type === 'radio'" class="field-radio-group">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-for="opt in field.options"
|
|
|
|
|
|
:key="opt.value"
|
|
|
|
|
|
class="radio-item"
|
|
|
|
|
|
:class="{ active: (form[field.key] ?? field.default) === opt.value }"
|
|
|
|
|
|
@tap="handleRadioChange(field.key, opt.value)"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ opt.label }}
|
|
|
|
|
|
</view>
|
2026-05-18 13:54:57 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
<!-- 选择框 -->
|
|
|
|
|
|
<picker
|
|
|
|
|
|
v-else-if="field.type === 'select'"
|
|
|
|
|
|
mode="selector"
|
|
|
|
|
|
:range="field.options.map(opt => opt.label)"
|
|
|
|
|
|
:value="getSelectIndex(field, form[field.key])"
|
|
|
|
|
|
@change="(e: any) => {
|
|
|
|
|
|
const index = e.detail.value
|
|
|
|
|
|
form[field.key] = field.options[index].value
|
|
|
|
|
|
}"
|
|
|
|
|
|
>
|
|
|
|
|
|
<view class="field-input field-picker">
|
|
|
|
|
|
{{ getSelectedLabel(field, form[field.key]) || field.placeholder }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</picker>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 日期选择器 -->
|
|
|
|
|
|
<picker
|
|
|
|
|
|
v-else-if="field.type === 'date'"
|
|
|
|
|
|
mode="date"
|
|
|
|
|
|
:value="form[field.key] || ''"
|
|
|
|
|
|
@change="(e: any) => (form[field.key] = e.detail.value)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<view class="field-input field-picker">
|
|
|
|
|
|
{{ form[field.key] || field.placeholder }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</picker>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 文本域 -->
|
|
|
|
|
|
<textarea
|
|
|
|
|
|
v-else-if="field.type === 'textarea'"
|
|
|
|
|
|
class="field-input field-textarea"
|
|
|
|
|
|
:maxlength="field.maxlength"
|
|
|
|
|
|
:placeholder="field.placeholder"
|
|
|
|
|
|
:value="form[field.key] || ''"
|
|
|
|
|
|
placeholder-class="field-ph"
|
|
|
|
|
|
@input="(e: any) => handleInput(field.key, e.detail.value)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 普通输入框 -->
|
|
|
|
|
|
<input
|
|
|
|
|
|
v-else
|
|
|
|
|
|
class="field-input"
|
|
|
|
|
|
:type="field.type"
|
|
|
|
|
|
:maxlength="field.maxlength"
|
|
|
|
|
|
:placeholder="getFieldPlaceholder(field)"
|
|
|
|
|
|
:value="form[field.key] || ''"
|
|
|
|
|
|
placeholder-class="field-ph"
|
|
|
|
|
|
confirm-type="done"
|
|
|
|
|
|
@input="(e: any) => handleInput(field.key, e.detail.value)"
|
|
|
|
|
|
@blur="(e: any) => (form[field.key] = e.detail.value)"
|
|
|
|
|
|
@confirm="(e: any) => (form[field.key] = e.detail.value)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</template>
|
2026-05-16 15:47:07 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 查询按钮 -->
|
|
|
|
|
|
<button
|
|
|
|
|
|
class="query-btn"
|
|
|
|
|
|
:disabled="loading"
|
|
|
|
|
|
@tap="handleQuery"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ loading ? '查询中...' : '立即查询' }}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 错误提示 -->
|
|
|
|
|
|
<view v-if="error" class="msg-area msg-error">
|
|
|
|
|
|
<text class="msg-text">{{ error }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
<!-- 游戏类工具特殊展示 -->
|
|
|
|
|
|
<view v-if="tool?.isGame && result" class="game-area">
|
|
|
|
|
|
<!-- 成语接龙特殊展示 -->
|
|
|
|
|
|
<template v-if="toolKey === 'chengyujielong'">
|
|
|
|
|
|
<!-- 用户输入的成语 -->
|
|
|
|
|
|
<view v-if="form.word" class="chain-user-input">
|
|
|
|
|
|
<text class="chain-user-label">你的成语:</text>
|
|
|
|
|
|
<text class="chain-user-value">{{ form.word }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 系统接龙的结果 -->
|
|
|
|
|
|
<view v-if="result && result.word" class="chain-result">
|
|
|
|
|
|
<view class="chain-success">
|
|
|
|
|
|
<text class="chain-success-icon">🔗</text>
|
|
|
|
|
|
<view class="chain-success-content">
|
|
|
|
|
|
<text class="chain-idiom">{{ result.word }}</text>
|
|
|
|
|
|
<text v-if="result.pinyin" class="chain-pinyin">({{ result.pinyin }})</text>
|
|
|
|
|
|
<text v-if="result.jieshi" class="chain-explain">:{{ result.jieshi }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 快速填入按钮 -->
|
|
|
|
|
|
<button class="chain-quick-btn" @tap="handleQuickFill">
|
|
|
|
|
|
📝 用这个继续接龙
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 空状态提示 -->
|
|
|
|
|
|
<view v-if="!result" class="chain-empty">
|
|
|
|
|
|
<text class="chain-empty-text">输入成语后,系统会自动接龙</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 填字游戏(成语填字、诗词填空) -->
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<!-- 难度标签 -->
|
|
|
|
|
|
<view v-if="result.diff" class="game-diff">
|
|
|
|
|
|
<text class="game-diff-text">{{ getDisplayValue('diff', result.diff) }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 题目 -->
|
|
|
|
|
|
<view class="game-question">
|
|
|
|
|
|
<text class="game-question-text">{{ result.question }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 选项按钮 -->
|
|
|
|
|
|
<view class="game-options">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-for="(option, index) in gameOptions"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
class="game-option"
|
|
|
|
|
|
:class="{
|
|
|
|
|
|
'game-option-selected': selectedOption === option.value,
|
|
|
|
|
|
'game-option-correct': answered && option.isCorrect,
|
|
|
|
|
|
'game-option-wrong': answered && selectedOption === option.value && !option.isCorrect,
|
|
|
|
|
|
}"
|
|
|
|
|
|
@tap="handleOptionClick(option)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<text class="game-option-text">{{ option.label }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 答案和解释 -->
|
|
|
|
|
|
<view v-if="answered" class="game-result">
|
|
|
|
|
|
<!-- 答对提示 -->
|
|
|
|
|
|
<view v-if="answeredCorrect" class="game-status game-status-correct">
|
|
|
|
|
|
<text class="game-status-text">🎉 回答正确!</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 答错提示 -->
|
|
|
|
|
|
<view v-else class="game-status game-status-wrong">
|
|
|
|
|
|
<text class="game-status-text">❌ 回答错误</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 成语填字:显示完整成语和解释 -->
|
|
|
|
|
|
<template v-if="toolKey === 'idiom-quiz'">
|
|
|
|
|
|
<view class="game-answer">
|
|
|
|
|
|
<text class="game-answer-label">完整成语:</text>
|
|
|
|
|
|
<text class="game-answer-value">{{ result.full }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="game-explan">
|
|
|
|
|
|
<text class="game-explan-label">成语解释:</text>
|
|
|
|
|
|
<text class="game-explan-value">{{ result.explan }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 诗词填空:显示完整诗句和详细信息 -->
|
|
|
|
|
|
<template v-else-if="toolKey === 'poem-fill'">
|
|
|
|
|
|
<view class="game-answer">
|
|
|
|
|
|
<text class="game-answer-label">完整诗句:</text>
|
|
|
|
|
|
<text class="game-answer-value">{{ result.full }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="game-poem-info">
|
|
|
|
|
|
<view v-if="result.title" class="game-poem-item">
|
|
|
|
|
|
<text class="game-poem-label">诗名:</text>
|
|
|
|
|
|
<text class="game-poem-value">{{ result.title }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.author" class="game-poem-item">
|
|
|
|
|
|
<text class="game-poem-label">作者:</text>
|
|
|
|
|
|
<text class="game-poem-value">{{ result.author }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.dynasty" class="game-poem-item">
|
|
|
|
|
|
<text class="game-poem-label">朝代:</text>
|
|
|
|
|
|
<text class="game-poem-value">{{ result.dynasty }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.category" class="game-poem-item">
|
|
|
|
|
|
<text class="game-poem-label">分类:</text>
|
|
|
|
|
|
<text class="game-poem-value">{{ result.category }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.note" class="game-explan">
|
|
|
|
|
|
<text class="game-explan-label">注释:</text>
|
|
|
|
|
|
<text class="game-explan-value">{{ result.note }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 再来一题按钮 -->
|
|
|
|
|
|
<button class="game-restart-btn" @tap="handleRestart">
|
|
|
|
|
|
🔄 再来一题
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
<!-- 结果展示 - 普通键值对 -->
|
2026-05-20 14:48:07 +08:00
|
|
|
|
<view v-if="resultEntries.length > 0 && tool?.resultType !== 'list' && !tool?.isGame" class="result-area">
|
2026-05-16 15:47:07 +08:00
|
|
|
|
<view class="result-title">查询结果</view>
|
2026-05-20 14:48:07 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 字典类型特殊显示 -->
|
|
|
|
|
|
<view v-if="tool?.resultType === 'dict'" class="dict-result">
|
|
|
|
|
|
<!-- 汉字标题 -->
|
|
|
|
|
|
<view v-if="result.word" class="dict-word">
|
|
|
|
|
|
<text class="dict-word-text">{{ result.word }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 基础信息卡片 -->
|
|
|
|
|
|
<view v-if="result.py || result.pyyb || result.wubi || result.bihua || result.bushou" class="dict-basic-info">
|
|
|
|
|
|
<view v-if="result.py" class="dict-info-item">
|
|
|
|
|
|
<text class="dict-info-label">拼音</text>
|
|
|
|
|
|
<text class="dict-info-value">{{ result.py }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.pyyb" class="dict-info-item">
|
|
|
|
|
|
<text class="dict-info-label">拼音音标</text>
|
|
|
|
|
|
<text class="dict-info-value">{{ result.pyyb }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.wubi" class="dict-info-item">
|
|
|
|
|
|
<text class="dict-info-label">五笔</text>
|
|
|
|
|
|
<text class="dict-info-value">{{ result.wubi }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.bihua" class="dict-info-item">
|
|
|
|
|
|
<text class="dict-info-label">笔画</text>
|
|
|
|
|
|
<text class="dict-info-value">{{ result.bihua }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.bushou" class="dict-info-item">
|
|
|
|
|
|
<text class="dict-info-label">部首</text>
|
|
|
|
|
|
<text class="dict-info-value">{{ result.bushou }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="result.bishun" class="dict-info-item">
|
|
|
|
|
|
<text class="dict-info-label">笔顺</text>
|
|
|
|
|
|
<text class="dict-info-value">{{ result.bishun }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 释义卡片 -->
|
|
|
|
|
|
<view v-if="result.content" class="dict-content">
|
|
|
|
|
|
<text class="dict-content-title">释义</text>
|
|
|
|
|
|
<text class="dict-content-text">{{ result.content }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 详细解释卡片 -->
|
|
|
|
|
|
<view v-if="result.explain" class="dict-explain">
|
|
|
|
|
|
<text class="dict-explain-title">详细解释</text>
|
|
|
|
|
|
<text class="dict-explain-text">{{ result.explain }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 普通列表显示 -->
|
|
|
|
|
|
<view v-else class="result-list">
|
2026-05-16 15:47:07 +08:00
|
|
|
|
<view
|
|
|
|
|
|
v-for="item in resultEntries"
|
|
|
|
|
|
:key="item.key"
|
|
|
|
|
|
class="result-row"
|
|
|
|
|
|
>
|
|
|
|
|
|
<text class="result-label">{{ item.label }}</text>
|
|
|
|
|
|
<!-- 隐藏字段:点击显示/隐藏 -->
|
|
|
|
|
|
<view v-if="item.hidden" class="result-reveal-wrap">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-if="!revealedKeys.has(item.key)"
|
|
|
|
|
|
class="result-reveal-btn"
|
|
|
|
|
|
@tap="toggleReveal(item.key)"
|
|
|
|
|
|
>
|
|
|
|
|
|
点击查看
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<text class="result-value">{{ item.value }}</text>
|
|
|
|
|
|
<text class="result-hide-btn" @tap="toggleReveal(item.key)">收起</text>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</view>
|
2026-05-20 14:48:07 +08:00
|
|
|
|
<!-- 多行文本 -->
|
|
|
|
|
|
<text v-else-if="typeof item.value === 'string' && item.value.length > 50" class="result-value result-multiline">{{ item.value }}</text>
|
2026-05-16 15:47:07 +08:00
|
|
|
|
<!-- 普通字段 -->
|
|
|
|
|
|
<text v-else class="result-value">{{ item.value }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
2026-05-18 13:54:57 +08:00
|
|
|
|
<!-- 结果展示 - 子列表型 (如油价明细) -->
|
|
|
|
|
|
<view v-if="subResultList.length > 0" class="result-area">
|
|
|
|
|
|
<view class="result-title">详细列表</view>
|
|
|
|
|
|
<view class="result-card-list">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-for="(item, idx) in subResultList"
|
|
|
|
|
|
:key="idx"
|
|
|
|
|
|
class="result-card-item"
|
|
|
|
|
|
>
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-for="([fieldKey, fieldLabel], fIdx) in subResultLabelEntries"
|
|
|
|
|
|
:key="fieldKey"
|
|
|
|
|
|
class="card-item-row"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template v-if="item[fieldKey] !== undefined && item[fieldKey] !== ''">
|
|
|
|
|
|
<text v-if="fIdx === 0" class="card-item-index">{{ idx + 1 }}</text>
|
|
|
|
|
|
<text v-else class="card-item-index-placeholder" />
|
|
|
|
|
|
<text class="card-item-field-label">{{ typeof fieldLabel === 'object' ? fieldLabel.label : fieldLabel }}</text>
|
|
|
|
|
|
<text class="card-item-field-value">{{ item[fieldKey] }}</text>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
<!-- 结果展示 - 列表型 -->
|
|
|
|
|
|
<view v-if="resultList.length > 0" class="result-area">
|
|
|
|
|
|
<view class="result-title">查询结果</view>
|
|
|
|
|
|
<view class="result-card-list">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-for="(item, idx) in resultList"
|
|
|
|
|
|
:key="idx"
|
|
|
|
|
|
class="result-card-item"
|
|
|
|
|
|
>
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-for="([fieldKey, fieldLabel], fIdx) in listLabelEntries"
|
|
|
|
|
|
:key="fieldKey"
|
|
|
|
|
|
class="card-item-row"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template v-if="item[fieldKey] !== undefined && item[fieldKey] !== ''">
|
|
|
|
|
|
<text v-if="fIdx === 0" class="card-item-index">{{ idx + 1 }}</text>
|
|
|
|
|
|
<text v-else class="card-item-index-placeholder" />
|
|
|
|
|
|
<text class="card-item-field-label">{{ typeof fieldLabel === 'object' ? fieldLabel.label : fieldLabel }}</text>
|
2026-05-20 14:48:07 +08:00
|
|
|
|
<!-- 隐藏字段:点击显示/隐藏 -->
|
|
|
|
|
|
<view v-if="typeof fieldLabel === 'object' && fieldLabel.hidden" class="card-item-reveal-wrap">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-if="!revealedKeys.has(`${idx}-${fieldKey}`)"
|
|
|
|
|
|
class="card-item-reveal-btn"
|
|
|
|
|
|
@tap="toggleReveal(`${idx}-${fieldKey}`)"
|
|
|
|
|
|
>
|
|
|
|
|
|
点击查看
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<text class="card-item-field-value">{{ item[fieldKey] }}</text>
|
|
|
|
|
|
<text class="card-item-hide-btn" @tap="toggleReveal(`${idx}-${fieldKey}`)">收起</text>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 普通字段 -->
|
|
|
|
|
|
<text v-else class="card-item-field-value">{{ item[fieldKey] }}</text>
|
2026-05-16 15:47:07 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<view v-else class="empty">
|
|
|
|
|
|
<text class="empty-text">未找到该工具</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.page-root {
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.scrollarea {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
height: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.page {
|
|
|
|
|
|
padding: 24rpx 24rpx 40rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card {
|
|
|
|
|
|
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
|
|
|
|
|
border-radius: 24rpx;
|
|
|
|
|
|
padding: 32rpx 28rpx;
|
|
|
|
|
|
border: 1rpx solid #e5e6f0;
|
|
|
|
|
|
box-shadow:
|
|
|
|
|
|
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
|
|
|
|
|
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-desc {
|
|
|
|
|
|
margin-bottom: 28rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.desc-text {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-area {
|
|
|
|
|
|
margin-bottom: 28rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field {
|
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field-label {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #4e5969;
|
|
|
|
|
|
margin-bottom: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field-input {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
|
background: #f7f8fa;
|
|
|
|
|
|
border: 1rpx solid #e5e6f0;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-18 13:54:57 +08:00
|
|
|
|
.field-radio-group {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 16rpx;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.radio-item {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
min-width: 140rpx;
|
|
|
|
|
|
height: 72rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
background: #f7f8fa;
|
|
|
|
|
|
border: 1rpx solid #e5e6f0;
|
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #4e5969;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.radio-item.active {
|
|
|
|
|
|
background: #e8f3ff;
|
|
|
|
|
|
border-color: #1768ff;
|
|
|
|
|
|
color: #1768ff;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
.field-picker {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field-picker:empty::before {
|
|
|
|
|
|
content: attr(placeholder);
|
|
|
|
|
|
color: #c9cdd4;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field-textarea {
|
|
|
|
|
|
height: 200rpx;
|
|
|
|
|
|
padding: 16rpx 24rpx;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.field-ph {
|
|
|
|
|
|
color: #c9cdd4;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.query-btn {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 88rpx;
|
|
|
|
|
|
line-height: 88rpx;
|
|
|
|
|
|
background: linear-gradient(135deg, #1768ff, #4e8cff);
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.query-btn[disabled] {
|
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.msg-area {
|
|
|
|
|
|
padding: 16rpx 20rpx;
|
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.msg-error {
|
|
|
|
|
|
background: #fff2f0;
|
|
|
|
|
|
border: 1rpx solid #ffccc7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.msg-text {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #f53f3f;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
/* 字典结果样式 */
|
|
|
|
|
|
.dict-result {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-word {
|
|
|
|
|
|
background: linear-gradient(135deg, #1768ff, #4e8cff);
|
|
|
|
|
|
padding: 32rpx;
|
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-word-text {
|
|
|
|
|
|
font-size: 72rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-basic-info {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(2, 1fr);
|
|
|
|
|
|
gap: 16rpx;
|
|
|
|
|
|
padding: 0 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-info-item {
|
|
|
|
|
|
background: #f7f8fa;
|
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-info-label {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-info-value {
|
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-content,
|
|
|
|
|
|
.dict-explain {
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border: 1rpx solid #e5e6f0;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
padding: 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-content-title,
|
|
|
|
|
|
.dict-explain-title {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.dict-content-text,
|
|
|
|
|
|
.dict-explain-text {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #4e5969;
|
|
|
|
|
|
line-height: 1.8;
|
|
|
|
|
|
white-space: pre-wrap;
|
|
|
|
|
|
word-wrap: break-word;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
.result-area {
|
|
|
|
|
|
margin-top: 8rpx;
|
|
|
|
|
|
padding-top: 24rpx;
|
|
|
|
|
|
border-top: 1rpx solid #f2f3f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-title {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-list {
|
|
|
|
|
|
background: #f7f8fa;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
padding: 8rpx 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 16rpx 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-label {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-value {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
.result-multiline {
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
line-height: 1.8;
|
|
|
|
|
|
word-wrap: break-word;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
.result-reveal-wrap {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
gap: 12rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-reveal-btn {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
background: linear-gradient(135deg, #1768ff, #4e8cff);
|
|
|
|
|
|
padding: 6rpx 24rpx;
|
|
|
|
|
|
border-radius: 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-hide-btn {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 120rpx 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty-text {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 列表型结果卡片 */
|
|
|
|
|
|
.result-card-list {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-card-item {
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border: 1rpx solid #e5e6f0;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
padding: 20rpx 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-item-row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
gap: 12rpx;
|
|
|
|
|
|
padding: 4rpx 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-item-index {
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
width: 40rpx;
|
|
|
|
|
|
height: 40rpx;
|
|
|
|
|
|
line-height: 40rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
background: linear-gradient(135deg, #1768ff, #4e8cff);
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-item-index-placeholder {
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
width: 40rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-item-field-label {
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
min-width: 80rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-item-field-value {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 14:48:07 +08:00
|
|
|
|
/* 列表卡片中的隐藏字段 */
|
|
|
|
|
|
.card-item-reveal-wrap {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 12rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-item-reveal-btn {
|
|
|
|
|
|
padding: 8rpx 24rpx;
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
background: linear-gradient(135deg, #1768ff, #4e8cff);
|
|
|
|
|
|
border-radius: 24rpx;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-item-hide-btn {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 15:47:07 +08:00
|
|
|
|
/* 自定义选择器样式 */
|
|
|
|
|
|
.picker-container {
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
border-radius: 20rpx 20rpx 0 0;
|
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
|
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.picker-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 0 20rpx;
|
|
|
|
|
|
height: 88rpx;
|
|
|
|
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.picker-header text {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.picker-header text:first-child {
|
|
|
|
|
|
color: #606266;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.picker-header text:last-child {
|
|
|
|
|
|
color: #1768ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.picker-view {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 400rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.picker-item {
|
|
|
|
|
|
line-height: 100rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
2026-05-20 14:48:07 +08:00
|
|
|
|
|
|
|
|
|
|
/* 游戏区域样式 */
|
|
|
|
|
|
.game-area {
|
|
|
|
|
|
margin-top: 28rpx;
|
|
|
|
|
|
padding: 28rpx;
|
|
|
|
|
|
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
border: 2rpx solid #e5e6f0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-diff {
|
|
|
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-diff-text {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
background: #f7f8fa;
|
|
|
|
|
|
padding: 8rpx 20rpx;
|
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-question {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 40rpx 20rpx;
|
|
|
|
|
|
margin-bottom: 32rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-question-text {
|
|
|
|
|
|
font-size: 48rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-options {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(2, 1fr);
|
|
|
|
|
|
gap: 16rpx;
|
|
|
|
|
|
margin-bottom: 32rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-option {
|
|
|
|
|
|
height: 88rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border: 2rpx solid #e5e6f0;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-option:active {
|
|
|
|
|
|
transform: scale(0.98);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-option-selected {
|
|
|
|
|
|
border-color: #1768ff;
|
|
|
|
|
|
background: #e8f3ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-option-correct {
|
|
|
|
|
|
border-color: #00b42a;
|
|
|
|
|
|
background: #e8ffeb;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-option-wrong {
|
|
|
|
|
|
border-color: #f53f3f;
|
|
|
|
|
|
background: #ffe8e8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-option-text {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-result {
|
|
|
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
|
padding: 24rpx;
|
|
|
|
|
|
background: #f7f8fa;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-status {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 16rpx;
|
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-status-correct {
|
|
|
|
|
|
background: #e8ffeb;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-status-wrong {
|
|
|
|
|
|
background: #ffe8e8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-status-text {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-answer {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: baseline;
|
|
|
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-answer-label {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-answer-value {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
margin-left: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-explan {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-explan-label {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-explan-value {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #4e5969;
|
|
|
|
|
|
line-height: 1.8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 诗词信息样式 */
|
|
|
|
|
|
.game-poem-info {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(2, 1fr);
|
|
|
|
|
|
gap: 12rpx;
|
|
|
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
|
padding: 16rpx;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-poem-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: baseline;
|
|
|
|
|
|
gap: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-poem-label {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-poem-value {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-restart-btn {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 88rpx;
|
|
|
|
|
|
line-height: 88rpx;
|
|
|
|
|
|
background: linear-gradient(135deg, #1768ff, #4e8cff);
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
margin-top: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-restart-btn[disabled] {
|
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 成语接龙游戏样式 */
|
|
|
|
|
|
.chain-user-input {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 12rpx;
|
|
|
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
|
background: linear-gradient(135deg, #e8f3ff 0%, #ffffff 100%);
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-user-label {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-user-value {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1768ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-result {
|
|
|
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-success {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
gap: 16rpx;
|
|
|
|
|
|
padding: 24rpx;
|
|
|
|
|
|
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
|
|
|
|
|
border: 2rpx solid #e8f3ff;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-success-icon {
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
width: 48rpx;
|
|
|
|
|
|
height: 48rpx;
|
|
|
|
|
|
line-height: 48rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
background: linear-gradient(135deg, #00b42a, #36cfc9);
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-success-content {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-idiom {
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1d2129;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-pinyin {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-explain {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #4e5969;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-quick-btn {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 88rpx;
|
|
|
|
|
|
line-height: 88rpx;
|
|
|
|
|
|
background: linear-gradient(135deg, #1768ff, #4e8cff);
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
margin-top: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-empty {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 40rpx 0;
|
|
|
|
|
|
color: #86909c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chain-empty-text {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
}
|
2026-05-16 15:47:07 +08:00
|
|
|
|
</style>
|