feat: add comprehensive backend topics and fix build issues

## 新增内容

### 附录文档扩展
- 扩展前端项目架构文档 (frontend-project-architecture.md)
- 扩展后端项目架构文档 (backend-project-architecture.md)
- 扩展数据治理文档 (data-governance.md)
- 扩展数据可视化文档 (data-visualization.md)
- 扩展分布式系统文档 (distributed-systems.md)
- 扩展高可用文档 (high-availability.md)
- 扩展单体到微服务文档 (monolith-to-microservices.md)
- 扩展系统设计方法论文档 (system-design-methodology.md)
- 扩展 Docker 容器文档 (docker-containers.md)
- 扩展 Kubernetes 文档 (kubernetes.md)
- 扩展 Linux 基础文档 (linux-basics.md)
- 扩展神经网络文档 (neural-networks.md)

### 新增交互式组件
- 数据治理组件: DataQualityDemo, DataGovernanceFrameworkDemo, DataLineageDemo
- 数据可视化组件: ChartTypeSelectorDemo, DashboardLayoutDemo
- 分布式系统组件: CAPTheoremDemo, ConsistencyModelsDemo, DistributedChallengesDemo
- 高可用组件: AvailabilityCalculatorDemo, FailoverStrategyDemo
- 系统设计组件: SystemDesignStepsDemo, CapacityEstimationDemo
- Docker 容器组件: DockerArchitectureDemo, DockerLifecycleDemo
- Kubernetes 组件: K8sArchitectureDemo, K8sWorkloadsDemo
- Linux 基础组件: LinuxFileSystemDemo, LinuxCommandDemo, LinuxPermissionsDemo
- 神经网络组件: NeuronDemo, NetworkLayersDemo, NetworkArchitectureDemo
- 单体到微服务组件: ArchEvolutionDemo
- 项目架构组件: ProjectArchitectureComparisonDemo
- 附录导航组件: AppendixFlowMap

### 英文版重构
- 将 en-us 目录重命名为 en
- 更新相关配置和组件中的语言代码

## Bug 修复
- 修复 index.js 中重复的组件导入语句导致的 build 失败
- 恢复被注释的 InvertedIndexDemo 和 SearchRelevanceDemo 导入
- 修复 HomeFeatures.vue 中 en-us 与 config.mjs 中 en 不一致导致的语言切换问题

## 其他改进
- 添加构建脚本 (scripts/build.mjs)
- 更新依赖版本
This commit is contained in:
sanbuphy
2026-02-26 04:35:28 +08:00
parent df51f84ab5
commit ef70b1d8e1
84 changed files with 12917 additions and 3477 deletions
@@ -155,7 +155,7 @@
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import { ref, computed, watch, onUnmounted } from 'vue'
const stage = ref(0)
const expandedOp = ref(-1)
@@ -313,15 +313,26 @@ function getDeviceStatus(i) {
return '等待'
}
const postTimer = ref(null)
const hwTimer = ref(null)
const bootTimer = ref(null)
onUnmounted(() => {
if (postTimer.value) clearInterval(postTimer.value)
if (hwTimer.value) clearInterval(hwTimer.value)
if (bootTimer.value) clearInterval(bootTimer.value)
})
// POST 自检动画
watch(() => stage.value, (newStage) => {
if (postTimer.value) clearInterval(postTimer.value)
if (newStage === 1) {
currentCheck.value = 0
const interval = setInterval(() => {
postTimer.value = setInterval(() => {
if (currentCheck.value < postItems.length) {
currentCheck.value++
} else {
clearInterval(interval)
if (postTimer.value) clearInterval(postTimer.value)
}
}, 600)
}
@@ -329,15 +340,16 @@ watch(() => stage.value, (newStage) => {
// 硬件初始化动画
watch(() => stage.value, (newStage) => {
if (hwTimer.value) clearInterval(hwTimer.value)
if (newStage === 2) {
activeHw.value = 0
hwProgress.value = 0
const interval = setInterval(() => {
hwTimer.value = setInterval(() => {
if (hwProgress.value < 100) {
hwProgress.value += 5
activeHw.value = Math.floor(hwProgress.value / 20) % hardwareItems.length
} else {
clearInterval(interval)
if (hwTimer.value) clearInterval(hwTimer.value)
}
}, 100)
}
@@ -345,11 +357,12 @@ watch(() => stage.value, (newStage) => {
// 启动设备搜索动画
watch(() => stage.value, (newStage) => {
if (bootTimer.value) clearInterval(bootTimer.value)
if (newStage === 3) {
currentDevice.value = 0
foundDevice.value = -1
let device = 0
const interval = setInterval(() => {
bootTimer.value = setInterval(() => {
if (device < bootDevices.length) {
currentDevice.value = device
// 假设第一个设备(硬盘)可启动
@@ -357,11 +370,11 @@ watch(() => stage.value, (newStage) => {
setTimeout(() => {
foundDevice.value = device
}, 400)
clearInterval(interval)
if (bootTimer.value) clearInterval(bootTimer.value)
}
device++
} else {
clearInterval(interval)
if (bootTimer.value) clearInterval(bootTimer.value)
}
}, 800)
}
@@ -387,6 +400,9 @@ function reset() {
hwProgress.value = 0
currentDevice.value = 0
foundDevice.value = -1
if (postTimer.value) clearInterval(postTimer.value)
if (hwTimer.value) clearInterval(hwTimer.value)
if (bootTimer.value) clearInterval(bootTimer.value)
}
</script>
@@ -47,12 +47,16 @@
</template>
<script setup>
import { ref } from 'vue'
import { ref, onUnmounted } from 'vue'
const selected = ref(0)
const visibleSteps = ref(0)
let timer = null
onUnmounted(() => {
if (timer) clearInterval(timer)
})
function selectMode(i) {
selected.value = i
visibleSteps.value = 0
@@ -451,7 +451,10 @@ function toggleAuto() {
} else {
autoRunning.value = true
autoTimer = setInterval(() => {
if (done.value) { stopAuto(); return }
if (done.value) {
stopAuto()
return
}
advance()
}, 900)
}
@@ -459,7 +462,10 @@ function toggleAuto() {
function stopAuto() {
autoRunning.value = false
if (autoTimer) { clearInterval(autoTimer); autoTimer = null }
if (autoTimer) {
clearInterval(autoTimer)
autoTimer = null
}
}
function reset() {
@@ -476,7 +482,9 @@ function reset() {
currentPhase.value = -1
}
onUnmounted(stopAuto)
onUnmounted(() => {
stopAuto()
})
</script>
<style scoped>
@@ -61,12 +61,17 @@ const updateClock = () => {
}
const runSequence = () => {
if (phaseTimer) clearTimeout(phaseTimer)
phase.value = 0
const delays = [1500, 1500, 1800]
let i = 0
const next = () => {
if (i < delays.length) {
phaseTimer = setTimeout(() => { phase.value = i + 1; i++; next() }, delays[i])
phaseTimer = setTimeout(() => {
phase.value = i + 1
i++
next()
}, delays[i])
}
}
next()
@@ -77,6 +82,7 @@ onMounted(() => {
timer = setInterval(updateClock, 30000)
runSequence()
})
onUnmounted(() => {
if (timer) clearInterval(timer)
if (phaseTimer) clearTimeout(phaseTimer)
@@ -165,7 +165,7 @@ onMounted(() => {
})
onUnmounted(() => {
clearInterval(timer)
if (timer) clearInterval(timer)
})
</script>
@@ -145,7 +145,7 @@ onMounted(() => {
})
onUnmounted(() => {
clearInterval(timer)
if (timer) clearInterval(timer)
})
</script>
@@ -90,7 +90,7 @@ onMounted(() => {
})
onUnmounted(() => {
clearInterval(timer)
if (timer) clearInterval(timer)
})
</script>
@@ -418,23 +418,31 @@ onMounted(() => {
}, 1000)
})
const blTimer = ref(null)
const kernelTimer = ref(null)
const svcTimer = ref(null)
onUnmounted(() => {
if (timeInterval) clearInterval(timeInterval)
if (blTimer.value) clearInterval(blTimer.value)
if (kernelTimer.value) clearInterval(kernelTimer.value)
if (svcTimer.value) clearInterval(svcTimer.value)
})
// 引导程序动画
watch(() => stage.value, (newStage) => {
if (blTimer.value) clearInterval(blTimer.value)
if (newStage === 1) {
blStep.value = -1
blCodeLine.value = -1
let step = 0
const interval = setInterval(() => {
blTimer.value = setInterval(() => {
if (step < blSteps.length) {
blStep.value = step
blCodeLine.value = step + 1
step++
} else {
clearInterval(interval)
if (blTimer.value) clearInterval(blTimer.value)
}
}, 600)
}
@@ -442,14 +450,15 @@ watch(() => stage.value, (newStage) => {
// 内核加载动画
watch(() => stage.value, (newStage) => {
if (kernelTimer.value) clearInterval(kernelTimer.value)
if (newStage === 2) {
kernelProgress.value = 0
kernelName.value = Math.random() > 0.5 ? 'ntoskrnl.exe' : 'vmlinuz'
const interval = setInterval(() => {
kernelTimer.value = setInterval(() => {
if (kernelProgress.value < 100) {
kernelProgress.value += 4
} else {
clearInterval(interval)
if (kernelTimer.value) clearInterval(kernelTimer.value)
}
}, 80)
}
@@ -457,13 +466,14 @@ watch(() => stage.value, (newStage) => {
// 服务启动动画
watch(() => stage.value, (newStage) => {
if (svcTimer.value) clearInterval(svcTimer.value)
if (newStage === 3) {
svcProgress.value = 0
const interval = setInterval(() => {
svcTimer.value = setInterval(() => {
if (svcProgress.value < 100) {
svcProgress.value += 3
} else {
clearInterval(interval)
if (svcTimer.value) clearInterval(svcTimer.value)
}
}, 100)
}
@@ -99,8 +99,8 @@ onMounted(() => {
})
onUnmounted(() => {
clearInterval(timer)
clearTimeout(switchTimer)
if (timer) clearInterval(timer)
if (switchTimer) clearTimeout(switchTimer)
})
const currentTask = computed(() => processes.value[currentIdx.value])
@@ -98,7 +98,7 @@ onMounted(() => {
})
onUnmounted(() => {
clearInterval(timer)
if (timer) clearInterval(timer)
})
</script>
@@ -123,13 +123,14 @@
</template>
<script setup>
import { ref } from 'vue'
import { ref, onUnmounted } from 'vue'
const activeAlgo = ref('linear')
const targetNumber = ref(7)
const foundIndex = ref(-1)
const searchStep = ref(-1)
const searching = ref(false)
const searchTimer = ref(null)
const numbers = ref([3, 7, 2, 9, 5, 1, 8, 4, 6, 10])
@@ -140,24 +141,29 @@ const binaryRight = ref(9)
const binaryMid = ref(4)
const binaryFoundIndex = ref(-1)
onUnmounted(() => {
if (searchTimer.value) clearInterval(searchTimer.value)
})
const startLinearSearch = () => {
if (searchTimer.value) clearInterval(searchTimer.value)
searching.value = true
searchStep.value = -1
foundIndex.value = -1
let step = 0
const interval = setInterval(() => {
searchTimer.value = setInterval(() => {
if (step < numbers.value.length) {
searchStep.value = step
if (numbers.value[step] === targetNumber.value) {
foundIndex.value = step
searching.value = false
clearInterval(interval)
if (searchTimer.value) clearInterval(searchTimer.value)
}
step++
} else {
searching.value = false
clearInterval(interval)
if (searchTimer.value) clearInterval(searchTimer.value)
}
}, 500)
}
@@ -123,24 +123,30 @@
</template>
<script setup>
import { ref, computed } from 'vue'
import { ref, onUnmounted } from 'vue'
const activeType = ref('serial')
const dataBits = ref(['1', '0', '1', '1', '0', '0', '1', '0'])
const dataBits = ref([1, 0, 1, 1, 0, 0, 1, 0])
const receivedBits = ref(['-', '-', '-', '-', '-', '-', '-', '-'])
const sendingBit = ref(null)
const timer = ref(null)
onUnmounted(() => {
if (timer.value) clearInterval(timer.value)
})
const startTransmission = () => {
if (timer.value) clearInterval(timer.value)
if (activeType.value === 'serial') {
receivedBits.value = ['-', '-', '-', '-', '-', '-', '-', '-']
let i = 0
const interval = setInterval(() => {
timer.value = setInterval(() => {
if (i < dataBits.value.length) {
sendingBit.value = i
receivedBits.value[i] = dataBits.value[i]
i++
} else {
clearInterval(interval)
if (timer.value) clearInterval(timer.value)
sendingBit.value = null
}
}, 300)
@@ -61,6 +61,7 @@ const steps = [
]
const autoPlay = () => {
if (timer) clearInterval(timer)
current.value = -1
playing.value = true
let i = 0
@@ -68,7 +69,7 @@ const autoPlay = () => {
current.value = i
i++
if (i >= steps.length) {
clearInterval(timer)
if (timer) clearInterval(timer)
playing.value = false
}
}, 800)