feat: 优化管理后台页面UI、修复TS编译错误、新增人生事件模块
- 优化 AI 配置列表页面:重构统计卡片、搜索表单、表格列展示 - 修复 3 处 TypeScript TS6133 编译错误,恢复构建 - 新增管理员修改密码和重置密码功能 - 优化小程序多个页面样式和交互 - 人生事件模块完善 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -4,15 +4,23 @@
|
||||
<!-- 分割线 -->
|
||||
<view v-if="block.type === 'hr'" class="markdown-hr"></view>
|
||||
|
||||
<text v-else-if="block.type === 'h1'" class="markdown-h1">{{ block.content }}</text>
|
||||
|
||||
<text v-else-if="block.type === 'h2'" class="markdown-h2">{{ block.content }}</text>
|
||||
|
||||
<!-- 三级标题 -->
|
||||
<text v-else-if="block.type === 'h3'" class="markdown-h3">{{ block.content }}</text>
|
||||
|
||||
<!-- 四级标题 -->
|
||||
<text v-else-if="block.type === 'h4'" class="markdown-h4">{{ block.content }}</text>
|
||||
|
||||
<view v-else-if="block.type === 'blockquote'" class="markdown-quote">
|
||||
<text>{{ block.content }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 列表项 -->
|
||||
<view v-else-if="block.type === 'li'" class="markdown-li">
|
||||
<text class="li-bullet">• </text>
|
||||
<text class="li-bullet">{{ block.marker }}</text>
|
||||
<text class="li-content">{{ block.content }}</text>
|
||||
</view>
|
||||
|
||||
@@ -53,6 +61,18 @@ const parsedBlocks = computed(() => {
|
||||
continue
|
||||
}
|
||||
|
||||
const h1Match = trimmed.match(/^#\s+(.+)/)
|
||||
if (h1Match) {
|
||||
blocks.push({ type: 'h1', content: h1Match[1] })
|
||||
continue
|
||||
}
|
||||
|
||||
const h2Match = trimmed.match(/^##\s+(.+)/)
|
||||
if (h2Match) {
|
||||
blocks.push({ type: 'h2', content: h2Match[1] })
|
||||
continue
|
||||
}
|
||||
|
||||
// 三级标题 ###
|
||||
const h3Match = trimmed.match(/^###\s+(.+)/)
|
||||
if (h3Match) {
|
||||
@@ -67,10 +87,16 @@ const parsedBlocks = computed(() => {
|
||||
continue
|
||||
}
|
||||
|
||||
// 列表项 * 或 -
|
||||
const liMatch = trimmed.match(/^[*\-]\s+(.+)/)
|
||||
const quoteMatch = trimmed.match(/^>\s+(.+)/)
|
||||
if (quoteMatch) {
|
||||
blocks.push({ type: 'blockquote', content: quoteMatch[1] })
|
||||
continue
|
||||
}
|
||||
|
||||
// 列表项 *、-、+ 或 1.
|
||||
const liMatch = trimmed.match(/^([*\-+]|\d+\.)\s+(.+)/)
|
||||
if (liMatch) {
|
||||
blocks.push({ type: 'li', content: liMatch[1] })
|
||||
blocks.push({ type: 'li', marker: /^\d+\./.test(liMatch[1]) ? liMatch[1] : '•', content: liMatch[2] })
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -117,7 +143,7 @@ const parseBoldText = (text) => {
|
||||
.markdown-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
gap: 14rpx;
|
||||
}
|
||||
|
||||
/* 分割线 */
|
||||
@@ -133,24 +159,52 @@ const parseBoldText = (text) => {
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
.markdown-h1,
|
||||
.markdown-h2,
|
||||
.markdown-h3 {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: rgba(243, 232, 255, 0.95);
|
||||
margin: 20rpx 0 12rpx 0;
|
||||
color: rgba(248, 244, 255, 0.96);
|
||||
line-height: 1.4;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.markdown-h1 {
|
||||
font-size: 32rpx;
|
||||
margin: 4rpx 0 10rpx 0;
|
||||
}
|
||||
|
||||
.markdown-h2 {
|
||||
font-size: 30rpx;
|
||||
margin: 14rpx 0 8rpx 0;
|
||||
}
|
||||
|
||||
.markdown-h3 {
|
||||
font-size: 28rpx;
|
||||
margin: 12rpx 0 6rpx 0;
|
||||
}
|
||||
|
||||
.markdown-h4 {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
font-size: 26rpx;
|
||||
font-weight: 800;
|
||||
color: rgba(243, 232, 255, 0.95);
|
||||
margin: 16rpx 0 8rpx 0;
|
||||
margin: 10rpx 0 4rpx 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.markdown-quote {
|
||||
padding: 16rpx 18rpx;
|
||||
border-left: 5rpx solid rgba(180, 108, 255, 0.8);
|
||||
border-radius: 14rpx;
|
||||
color: rgba(218, 202, 246, 0.82);
|
||||
background: rgba(168, 85, 247, 0.1);
|
||||
}
|
||||
|
||||
.markdown-quote text {
|
||||
font-size: 24rpx;
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
/* 列表项 */
|
||||
.markdown-li {
|
||||
display: flex;
|
||||
@@ -164,6 +218,7 @@ const parseBoldText = (text) => {
|
||||
color: #C084FC;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.5;
|
||||
min-width: 28rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import { ref, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const isPlaying = ref(false)
|
||||
const bottomPosition = ref('180rpx')
|
||||
const audioContext = null
|
||||
let audioInstance = null
|
||||
|
||||
// 背景音乐 URL - 使用原型中的音乐
|
||||
@@ -29,9 +28,18 @@ const initAudio = () => {
|
||||
audioInstance.loop = true
|
||||
audioInstance.autoplay = false
|
||||
|
||||
audioInstance.onPlay(() => {
|
||||
isPlaying.value = true
|
||||
})
|
||||
|
||||
audioInstance.onPause(() => {
|
||||
isPlaying.value = false
|
||||
})
|
||||
|
||||
audioInstance.onError((err) => {
|
||||
console.error('音乐播放失败:', err)
|
||||
isPlaying.value = false
|
||||
uni.showToast({ title: '音乐资源暂不可用', icon: 'none' })
|
||||
})
|
||||
|
||||
audioInstance.onEnded(() => {
|
||||
@@ -47,8 +55,7 @@ const toggleMusic = async () => {
|
||||
audioInstance.pause()
|
||||
} else {
|
||||
try {
|
||||
await audioInstance.play()
|
||||
isPlaying.value = true
|
||||
audioInstance.play()
|
||||
} catch (err) {
|
||||
console.error('音乐播放失败:', err)
|
||||
isPlaying.value = false
|
||||
|
||||
Reference in New Issue
Block a user