2025-02-14 23:14:54 +08:00
|
|
|
|
<script setup>
|
|
|
|
|
import { ref } from 'vue'
|
|
|
|
|
import Projects_projectBox from '../components/Projects_projectBox.vue'
|
|
|
|
|
|
|
|
|
|
// 搜索输入
|
|
|
|
|
const searchQuery = ref('')
|
|
|
|
|
|
|
|
|
|
// 用于生成随机图片尺寸
|
|
|
|
|
const imageURL = (r1, r2) => {
|
|
|
|
|
return `https://picsum.photos/${220 + Math.floor(r1 * 500)}/${220 + Math.floor(r2 * 500)}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 示例项目数据
|
|
|
|
|
const projects = ref([
|
|
|
|
|
{
|
|
|
|
|
id: 1,
|
|
|
|
|
name: '智能养殖系统',
|
|
|
|
|
author: ["张三", "李四"],
|
2025-02-15 18:06:26 +08:00
|
|
|
|
image: null,
|
2025-02-14 23:14:54 +08:00
|
|
|
|
status: '进行中',
|
|
|
|
|
tags: ['智能养殖', '自动喂养', '数据分析', '物联网']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
name: '绿色生态猪场',
|
|
|
|
|
author: ["王五", "赵六"],
|
2025-02-15 18:06:26 +08:00
|
|
|
|
image: null,
|
2025-02-14 23:14:54 +08:00
|
|
|
|
status: '已完成',
|
|
|
|
|
tags: ['环保', '生态养殖', '有机饲料', '循环利用']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
name: '基因优化猪种',
|
|
|
|
|
author: ["刘七", "杨八"],
|
2025-02-15 18:06:26 +08:00
|
|
|
|
image: null,
|
2025-02-14 23:14:54 +08:00
|
|
|
|
status: '待定',
|
|
|
|
|
tags: ['基因研究', '猪种改良', '优质肉类', '育种技术']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 4,
|
|
|
|
|
name: '猪肉生产透明化',
|
|
|
|
|
author: ["孙九", "钱十"],
|
2025-02-15 18:06:26 +08:00
|
|
|
|
image: null,
|
2025-02-14 23:14:54 +08:00
|
|
|
|
status: '暂停',
|
|
|
|
|
tags: ['透明供应链', '动物福利', '溯源技术', '肉品安全']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 5,
|
|
|
|
|
name: '猪场废弃物处理',
|
|
|
|
|
author: ["吴十一", "郑十二"],
|
|
|
|
|
image: imageURL(Math.random(), Math.random()),
|
|
|
|
|
status: '进行中',
|
|
|
|
|
tags: ['废物利用', '环保技术', '沼气发电', '饲料再生']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 6,
|
|
|
|
|
name: '猪肉替代品研发',
|
|
|
|
|
author: ["陈十三", "冯十四"],
|
|
|
|
|
image: imageURL(Math.random(), Math.random()),
|
|
|
|
|
status: '已完成',
|
|
|
|
|
tags: ['植物肉', '替代蛋白', '创新食品', '健康饮食']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 7,
|
|
|
|
|
name: '猪养殖智能监控',
|
|
|
|
|
author: ["郑十五", "许十六"],
|
|
|
|
|
image: imageURL(Math.random(), Math.random()),
|
|
|
|
|
status: '进行中',
|
|
|
|
|
tags: ['远程监控', '人工智能', '动物健康', '环境控制']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 8,
|
|
|
|
|
name: '猪饲料创新配方',
|
|
|
|
|
author: ["冯十七", "唐十八"],
|
|
|
|
|
image: imageURL(Math.random(), Math.random()),
|
|
|
|
|
status: '待定',
|
|
|
|
|
tags: ['营养优化', '创新饲料', '成本降低', '动物健康']
|
|
|
|
|
}
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解析搜索栏的输入,将其按空格拆分为多个关键字 tokens
|
|
|
|
|
* 例如输入 "Vue3 应用" => ["Vue3", "应用"]
|
|
|
|
|
*/
|
|
|
|
|
const parseSearchInput = (input) => {
|
|
|
|
|
return input
|
|
|
|
|
.trim()
|
|
|
|
|
.split(/\s+/)
|
|
|
|
|
.filter(Boolean) // 过滤空字符串
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据搜索栏输入,过滤项目
|
|
|
|
|
* 需求:搜索关键字既可以匹配项目名称,也可以匹配项目的 tags
|
|
|
|
|
* 并且多个关键字之间使用 "AND" 逻辑
|
|
|
|
|
*/
|
|
|
|
|
const filterProjects = () => {
|
|
|
|
|
// 如果没有输入任何搜索,直接返回全部
|
|
|
|
|
if (!searchQuery.value.trim()) {
|
|
|
|
|
return projects.value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取用户输入的关键词数组
|
|
|
|
|
const tokens = parseSearchInput(searchQuery.value.toLowerCase())
|
|
|
|
|
|
|
|
|
|
return projects.value.filter((project) => {
|
|
|
|
|
// 将项目名称和标签都转换为小写,用于匹配
|
|
|
|
|
const nameLower = project.name.toLowerCase()
|
|
|
|
|
const tagsLower = project.tags.map((tag) => tag.toLowerCase())
|
|
|
|
|
|
|
|
|
|
// 对于每个 token,都要求能在名称或标签中找到
|
|
|
|
|
return tokens.every((token) => {
|
|
|
|
|
// 名称包含 token,或某个标签包含 token
|
|
|
|
|
return (
|
|
|
|
|
nameLower.includes(token) ||
|
|
|
|
|
tagsLower.some((tag) => tag.includes(token))
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<div class="container">
|
|
|
|
|
<div class="filters">
|
|
|
|
|
<!-- 将标签的功能合并到搜索栏内 -->
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
v-model="searchQuery"
|
|
|
|
|
placeholder="搜索(多个标签或关键词,空格分割)"
|
|
|
|
|
class="search-bar"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 按照搜索结果展示项目 -->
|
|
|
|
|
<div class="projects">
|
|
|
|
|
<Projects_projectBox
|
|
|
|
|
v-for="project in filterProjects()"
|
|
|
|
|
:key="project.name"
|
|
|
|
|
:project="project"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.container {
|
|
|
|
|
height: calc(100vh - 100px);
|
|
|
|
|
width: 100%;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
overflow-x: hidden;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 20px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 筛选区域 */
|
|
|
|
|
.filters {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: 100%;
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 搜索栏 */
|
|
|
|
|
.search-bar {
|
|
|
|
|
padding: 10px;
|
|
|
|
|
margin: 20px 0;
|
|
|
|
|
width: 50%;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 项目区域 */
|
|
|
|
|
.projects {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 20px;
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 隐藏滚动条,可按需保留 */
|
|
|
|
|
::-webkit-scrollbar {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 亮色模式下可适当调整样式 */
|
|
|
|
|
.theme-light .search-bar {
|
|
|
|
|
border: 1px solid #ffb74d;
|
|
|
|
|
}
|
|
|
|
|
</style>
|