Files
property-resident-side/property-uniapp-project/pageSubPack/online-repair/personalSelectPoject.vue

215 lines
4.8 KiB
Vue

<template>
<view class="project-container">
<!-- 搜索框 -->
<view class="search-bar">
<input type="text" placeholder="请输入关键字搜索" v-model="searchKey" />
<uni-icons type="search" size="18"></uni-icons>
</view>
<!-- 分类+项目 -->
<view class="category-wrap">
<!-- 左侧分类 -->
<scroll-view scroll-y class="category-left">
<view
class="category-item"
:class="{ active: activeCategory === item.id }"
@click="selectCategory(item)"
v-for="item in categoryList"
:key="item.id"
>
{{ item.projectName }}
</view>
</scroll-view>
<!-- 右侧项目 -->
<scroll-view scroll-y class="category-right">
<view
class="project-item"
:class="{ active: selectedProject.id === item.id }"
@click="selectProject(item)"
v-for="item in currentProjectList"
:key="item.id"
>
{{ item.projectName }}
</view>
</scroll-view>
</view>
<!-- 空状态 -->
<view v-if="categoryList.length === 0 || currentProjectList.length === 0" class="empty-state">
<uni-icons type="info" size="30" color="#ccc"></uni-icons>
<text class="empty-text">
暂无维修项目
</text>
</view>
<!-- 确认按钮 -->
<button class="confirm-btn" @click="confirmSelect">确认</button>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getRepairProjectList } from '../api/api.js'
// 分类列表
const categoryList = ref([])
// 项目列表
const projectList = ref([])
// 选中状态
const activeCategory = ref(1)
const selectedProject = ref({}) // 选中的项目
const searchKey = ref('')
// 从接口获取个人报修项目列表
const fetchProjectList = async () => {
try {
const res = await getRepairProjectList({ projectType: '1' })
if (res.code === 200) {
const data = res.data || []
categoryList.value = data.map(item => ({ id: item.id, projectName: item.projectName }))
projectList.value = data.flatMap(item =>
(item.children || []).map(child => ({
id: child.id,
categoryId: item.id,
projectName: child.projectName
}))
)
activeCategory.value = categoryList.value[0]?.id || 1
}
} catch (e) {
uni.showToast({ title: '获取项目列表失败', icon: 'none' })
}
}
onLoad(() => {
fetchProjectList()
})
// 筛选当前分类的项目
const currentProjectList = computed(() => {
let list = projectList.value.filter(item => item.categoryId === activeCategory.value)
if (searchKey.value) {
list = list.filter(item => item.projectName.includes(searchKey.value))
}
return list
})
// 选择分类
const selectCategory = (item) => {
activeCategory.value = item.id
selectedProject.value = {} // 切换分类清空选中项目
}
// 选择项目
const selectProject = (item) => {
selectedProject.value = item
}
// 确认选择
const confirmSelect = () => {
if (!selectedProject.value.id) {
uni.showToast({ title: '请选择维修项目', icon: 'none' })
return
}
// 获取分类名称
const categoryName = categoryList.value.find(c => c.id === activeCategory.value).projectName
// 传递给表单页
uni.$emit('selectProject', {
name: `${categoryName}-${selectedProject.value.projectName}`,
id: selectedProject.value.id
})
uni.navigateBack({ delta: 1 })
}
</script>
<style scoped>
.project-container {
padding: 15px;
height: 100vh;
box-sizing: border-box;
display: flex;
flex-direction: column;
background: #fff;
}
.search-bar {
display: flex;
align-items: center;
padding: 8px 10px;
background: #f5f5f5;
border-radius: 6px;
margin-bottom: 10px;
}
.search-bar input {
flex: 1;
font-size: 14px;
}
.category-wrap {
display: flex;
flex: 1;
margin-bottom: 20px;
}
.category-left {
width: 80px;
height: 100%;
background: #f8f8f8;
border-radius: 6px 0 0 6px;
}
.category-item {
padding: 12px 10px;
text-align: center;
font-size: 14px;
border-bottom: 1px solid #eee;
}
.category-item.active {
background: #fff;
color: #007aff;
font-weight: bold;
}
.category-right {
flex: 1;
height: 100%;
background: #fff;
border-radius: 0 6px 6px 0;
padding: 10px;
}
.project-item {
padding: 12px 10px;
font-size: 14px;
border-bottom: 1px solid #eee;
}
.project-item.active {
color: #007aff;
font-weight: bold;
}
.confirm-btn {
width: 100%;
height: 44px;
line-height: 44px;
background: #007aff;
color: #fff;
border-radius: 8px;
font-size: 16px;
}
/* 空状态 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
color: #ccc;
}
.empty-text {
font-size: 32rpx;
color: #999;
margin-top: 20rpx;
margin-bottom: 10rpx;
}
</style>