对接在线报修的新增报修和报修详情接口

This commit is contained in:
zhouyanli
2026-04-30 14:28:22 +08:00
parent d183cb00c0
commit 95ccb1e3bc
7 changed files with 328 additions and 289 deletions

View File

@@ -113,12 +113,16 @@ export const getQueryRepair = (data) =>{
export const getHouseList = (data) =>{ export const getHouseList = (data) =>{
return get('/api/resident/my/house/list',data) return get('/api/resident/my/house/list',data)
} }
// 报修详情
export const getRepairDetail = (data) =>{
return get('/repairOrder/queryRepairDetail',data)
}
// 通用文件上传 // 通用文件上传
export const uploadImage = () => { export const uploadImage = () => {
return upload(''); return upload('');
} }
// 上传单张图片(请根据后端实际地址修改) // 上传单张图片
export const uploadFile = (filePath) => { export const uploadFile = (filePath) => {
return upload(filePath, '/common/upload'); return upload(filePath, '/common/upload');
} }

View File

@@ -11,6 +11,8 @@
</view> </view>
<!-- 报修类型Tab --> <!-- 报修类型Tab -->
<scroll-view class="scroll-container" scroll-y="true"
:lower-threshold="100">
<view class="repair-type-tabs"> <view class="repair-type-tabs">
<view <view
class="type-tab" class="type-tab"
@@ -66,22 +68,21 @@
<view class="repair-item" v-for="(item, index) in repairList" :key="index"> <view class="repair-item" v-for="(item, index) in repairList" :key="index">
<!-- 标题和状态 --> <!-- 标题和状态 -->
<view class="item-header"> <view class="item-header">
<text class="item-title">{{ item.title || '报修' }}</text> <text class="item-title">{{ item.houseName || '报修' }}</text>
<text class="item-status" :class="item.statusClass">{{ item.status }}</text> <text class="item-status" :class="item.statusClass">{{ item.status }}</text>
</view> </view>
<!-- 标签 --> <!-- 标签 -->
<view class="item-tags" v-if="item.repairTypeName || item.category"> <view class="item-tags" v-if="item.maintenanceItemName">
<text class="tag" v-if="item.repairTypeName">{{ item.repairTypeName }}</text> <text class="tag" v-if="item.maintenanceItemName">{{ item.maintenanceItemName }}</text>
<text class="tag" v-if="item.category">{{ item.category }}</text>
</view> </view>
<!-- 内容 --> <!-- 内容 -->
<view class="item-content"> <view class="item-content">
{{ item.content || item.description || '' }} {{ item.problem || '' }}
</view> </view>
<!-- 图片占位 --> <!-- 图片 -->
<view class="item-imgs" v-if="item.imageList && item.imageList.length"> <view class="item-imgs" v-if="item.imageList && item.imageList.length">
<view class="img-placeholder" v-for="(img, idx) in item.imageList" :key="idx"> <view class="img-placeholder" v-for="(img, idx) in item.imageList" :key="idx">
<image :src="typeof img === 'string' ? img : img.img" style="width: 100%;height: 100%;"></image> <image :src="typeof img === 'string' ? img : img.img" style="width: 100%;height: 100%;"></image>
@@ -90,7 +91,7 @@
<!-- 时间和详情 --> <!-- 时间和详情 -->
<view class="item-footer"> <view class="item-footer">
<text class="item-time">{{ item.time || item.createTime || '' }}</text> <text class="item-time">{{ item.orderDate || '' }}</text>
<text class="detail-btn" @click="goDetail(item)">报修详情</text> <text class="detail-btn" @click="goDetail(item)">报修详情</text>
</view> </view>
</view> </view>
@@ -100,12 +101,13 @@
<text class="empty-text">暂无数据</text> <text class="empty-text">暂无数据</text>
</view> </view>
</view> </view>
</scroll-view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, watch } from 'vue'; import { ref, watch } from 'vue';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad,onUnload } from '@dcloudio/uni-app';
import { getQueryRepair } from '../api/api.js'; import { getQueryRepair } from '../api/api.js';
// 报修类型public:公共报修personal:个人报修) // 报修类型public:公共报修personal:个人报修)
@@ -115,6 +117,9 @@ const activeStatus = ref('pending');
const repairList = ref([]); const repairList = ref([]);
const loading = ref(false); const loading = ref(false);
const pageNum = ref(1);
const pageSize = ref(10);
const maintenanceItemId = ref('');
// 状态映射 // 状态映射
const statusMap = { const statusMap = {
@@ -123,6 +128,13 @@ const statusMap = {
completed: { text: '已完成', class: 'completed', value: '2' } completed: { text: '已完成', class: 'completed', value: '2' }
}; };
const getStatusInfo = (val) => {
if (val === '0' || val === 0) return statusMap.pending;
if (val === '1' || val === 1) return statusMap.assigned;
if (val === '2' || val === 2) return statusMap.completed;
return null;
};
// 获取报修列表 // 获取报修列表
const fetchRepairList = async () => { const fetchRepairList = async () => {
const villageId = uni.getStorageSync('currentVillageId'); const villageId = uni.getStorageSync('currentVillageId');
@@ -133,23 +145,26 @@ const fetchRepairList = async () => {
loading.value = true; loading.value = true;
try { try {
const statusInfo = statusMap[activeStatus.value];
const params = { const params = {
villageId, villageId,
// 报修类型0-公共报修1-个人报修(按后端实际字段调整) // maintenanceItemId: maintenanceItemId.value,
projectType: activeType.value === 'public' ? '0' : '1', pageSize: pageSize.value,
// 状态0-待派单1-已派单2-已完成(按后端实际字段调整) pageNum: pageNum.value,
problemStatus: statusInfo.value problemStatus: statusMap[activeStatus.value].value
}; };
const res = await getQueryRepair(params); const res = await getQueryRepair(params);
console.log('接口返回:', res);
if (res.code === 200) { if (res.code === 200) {
// 按后端实际返回结构调整 // 兼容多种分页返回结构
const list = res.data|| []; const list = res.data?.rows || [];
repairList.value = list.map(item => ({ repairList.value = list.map(item => {
...item, const statusInfo = getStatusInfo(item.problemStatus);
status: statusInfo.text, const images = item.problemImageUrl ? item.problemImageUrl.split(',').filter(Boolean) : [];
statusClass: statusInfo.class if (statusInfo) {
})); return { ...item, status: statusInfo.text, statusClass: statusInfo.class, imageList: images };
}
return { ...item, imageList: images };
});
} else { } else {
uni.showToast({ title: res.msg || '获取失败', icon: 'none' }); uni.showToast({ title: res.msg || '获取失败', icon: 'none' });
} }
@@ -193,15 +208,18 @@ const goBack = () => {
} }
// 跳转报修详情 // 跳转报修详情
const goDetail = (item) => { const goDetail = (item) => {
const itemStr = encodeURIComponent(JSON.stringify(item))
uni.navigateTo({ uni.navigateTo({
url: `/pageSubPack/online-repair/repairDetail?item = ${itemStr}` url: `/pageSubPack/online-repair/repairDetail?id=${item.id}`
}); });
}; };
onLoad(() => { onLoad(() => {
fetchRepairList(); // maintenanceItemId.value = option.maintenanceProjectId || '' // 接收维修项目id
fetchRepairList()
}); });
onUnload(() =>{
})
</script> </script>
<style scoped> <style scoped>
@@ -251,6 +269,14 @@ onLoad(() => {
.nav-right { .nav-right {
width: 60rpx; width: 60rpx;
} }
/* 滚动区域 */
.scroll-container {
flex: 1;
width: 100%;
height: calc(100vh - 100px);
overflow-y: auto;
box-sizing: border-box;
}
/* 报修类型Tab */ /* 报修类型Tab */
.repair-type-tabs { .repair-type-tabs {
display: flex; display: flex;
@@ -338,6 +364,7 @@ onLoad(() => {
font-weight: bold; font-weight: bold;
color: #333; color: #333;
padding-right: 20rpx; padding-right: 20rpx;
width: 77%;
} }
.item-status { .item-status {
font-size: 14px; font-size: 14px;

View File

@@ -144,10 +144,8 @@
</template> </template>
<script setup> <script setup>
import { ref,computed,onMounted} from 'vue' import { ref, computed, onMounted } from 'vue'
import { import { onLoad, onUnload } from '@dcloudio/uni-app'
onLoad, onUnload
} from '@dcloudio/uni-app'
import { addQueryRepair, uploadFile } from '../api/api.js' import { addQueryRepair, uploadFile } from '../api/api.js'
import moment from 'moment/moment' import moment from 'moment/moment'
@@ -155,230 +153,167 @@ import moment from 'moment/moment'
const houseName = ref('') const houseName = ref('')
const houseId = ref('') const houseId = ref('')
const projectName = ref('') const projectName = ref('')
const projectId = ref('') // ✅ 修复新增项目ID
// 表单数据 // 表单数据
const form = ref({ const form = ref({
title: '', title: '',
desc: '', desc: '',
phone: '', phone: '',
datetime: '', // 默认时间 datetime: '',
images: [] images: []
}) })
// ========== 基础数据 ========== // ========== 基础数据 ==========
const timePopupRef = ref(null) const timePopupRef = ref(null)
// 初始时间() const selectedTime = ref(moment().hour(9).minute(30).second(0))
const selectedTime = ref(moment().hour(9).minute(30).second(0)); const tempTime = ref(moment().hour(9).minute(30).second(0))
// 选择的时间
const tempTime = ref(moment().hour(9).minute(30).second(0));
// ========== 时间选择列数据 ========== // ========== 时间选择列数据 ✅ 修复:固定小时/分钟,不跟随当前时间 ==========
// 日期列表(今天、明天、后天)
const dateList = ref([ const dateList = ref([
{ label: '(今天)', value: moment().format('YYYY-MM-DD') }, { label: '(今天)', value: moment().format('YYYY-MM-DD') },
{ label: '(明天)', value: moment().add(1, 'day').format('YYYY-MM-DD') }, { label: '(明天)', value: moment().add(1, 'day').format('YYYY-MM-DD') },
{ label: '(后天)', value: moment().add(2, 'day').format('YYYY-MM-DD') } { label: '(后天)', value: moment().add(2, 'day').format('YYYY-MM-DD') }
]); ])
// 小时列表()
const hourList = ref([ const hourList = ref([
{time: moment().hours(8).format('HH')}, { time: '08' }, { time: '09' }, { time: '10' }, { time: '11' },
{time:moment().hours(9).format('HH')}, { time: '13' }, { time: '14' }, { time: '15' }, { time: '16' },
{time:moment().hours(10).format('HH')}, { time: '17' }, { time: '18' }
{time:moment().hours(11).format('HH')}, ])
{time:moment().hours(13).format('HH')},
{time:moment().hours(14).format('HH')},
{time:moment().hours(15).format('HH')},
{time:moment().hours(16).format('HH')},
{time:moment().hours(17).format('HH')},
{time:moment().hours(18).format('HH')},
]);
// 分钟列表()
const minuteList = ref([ const minuteList = ref([
{minute:moment().minute(0).format('mm')}, { minute: '00' },
{minute:moment().minute(30).format('mm')} { minute: '30' }
]); ])
// ========== 选中状态 ========== // ========== 选中状态 ==========
const selectedDate = ref(dateList.value[0].value); const selectedDate = ref('')
const selectedHour = ref(hourList.value[1].time); // 默认选中8点 const selectedHour = ref('')
const selectedMinute = ref(minuteList.value[1].minute); // 默认选中00分 const selectedMinute = ref('')
// ========== 滚动配置 ========== // ========== 滚动配置 ==========
const itemHeight = 80; // 每个时间项的高度rpx const itemHeight = 80
const dateScrollTop = ref(0 * itemHeight); // 初始选中明天 const dateScrollTop = ref(0)
const hourScrollTop = ref(1 * itemHeight); // 初始选中9点 const hourScrollTop = ref(1)
const minuteScrollTop = ref(1 * itemHeight); // 初始选中00分 const minuteScrollTop = ref(1)
// ========== 显示文本 ========== // ========== 显示文本 ==========
const showTimeText = computed(() => { const showTimeText = computed(() => {
return selectedTime.value.format('YYYY-MM-DD HH:mm'); return selectedTime.value.format('YYYY-MM-DD HH:mm')
}); })
// ========== Popup 操作 ========== // ========== Popup 操作 ==========
// 打开时间弹窗
const openTimePopup = () => { const openTimePopup = () => {
// 打开前同步临时时间为当前选中时间 tempTime.value = moment(selectedTime.value)
tempTime.value = moment(selectedTime.value); selectedDate.value = tempTime.value.format('YYYY-MM-DD')
selectedDate.value = tempTime.value.format('YYYY-MM-DD'); selectedHour.value = tempTime.value.format('HH')
selectedHour.value = tempTime.value.format('HH'); selectedMinute.value = tempTime.value.format('mm')
selectedMinute.value = tempTime.value.format('mm'); syncScrollPosition()
timePopupRef.value?.open()
}
// 同步滚动位置
syncScrollPosition();
// 打开uni-popup
if(timePopupRef.value){
timePopupRef.value.open();
}
};
// 关闭时间弹窗
const closeTimePopup = () => { const closeTimePopup = () => {
timePopupRef.value.close(); timePopupRef.value?.close()
}; }
// 确认选择时间
const confirmTime = () => { const confirmTime = () => {
// 拼接选中的时间 const selectedDateTime = `${selectedDate.value} ${selectedHour.value}:${selectedMinute.value}`
const selectedDateTime = `${selectedDate.value} ${selectedHour.value}:${selectedMinute.value}`; selectedTime.value = moment(selectedDateTime, 'YYYY-MM-DD HH:mm')
selectedTime.value = moment(selectedDateTime, 'YYYY-MM-DD HH:mm');
// 给表单赋值
form.value.datetime = selectedTime.value.format('YYYY-MM-DD HH:mm') form.value.datetime = selectedTime.value.format('YYYY-MM-DD HH:mm')
// 关闭弹窗 closeTimePopup()
closeTimePopup();
// 提示
uni.showToast({ uni.showToast({
title: `已选择 ${selectedTime.value.format('MM月DD日 HH:mm')}`, title: `已选择 ${selectedTime.value.format('MM月DD日 HH:mm')}`,
icon: 'none' icon: 'none'
}); })
}; }
// ========== 滚动/点击选择逻辑 ========== // ========== 滚动/选择逻辑 ==========
// 同步滚动位置
const syncScrollPosition = () => { const syncScrollPosition = () => {
// 日期滚动位置 const dateIdx = dateList.value.findIndex(i => i.value === selectedDate.value)
const dateIndex = dateList.value.findIndex(item => item.value === selectedDate.value); const hourIdx = hourList.value.findIndex(i => i.time === selectedHour.value)
dateScrollTop.value = dateIndex * itemHeight; const minIdx = minuteList.value.findIndex(i => i.minute === selectedMinute.value)
// 小时滚动位置 dateScrollTop.value = dateIdx * itemHeight
const hourIndex = hourList.value.findIndex(item => item.time === selectedHour.value); hourScrollTop.value = hourIdx * itemHeight
hourScrollTop.value = hourIndex * itemHeight; minuteScrollTop.value = minIdx * itemHeight
}
// 分钟滚动位置
const minuteIndex = minuteList.value.findIndex(item => item.minute === selectedMinute.value);
minuteScrollTop.value = minuteIndex * itemHeight;
};
// 选择日期(点击)
const selectDate = (index) => { const selectDate = (index) => {
selectedDate.value = dateList.value[index].value; selectedDate.value = dateList.value[index].value
dateScrollTop.value = index * itemHeight; dateScrollTop.value = index * itemHeight
updateTempTime(); updateTempTime()
}; }
// 选择小时(点击)
const selectHour = (index) => { const selectHour = (index) => {
selectedHour.value = hourList.value[index].time; selectedHour.value = hourList.value[index].time
hourScrollTop.value = index * itemHeight; hourScrollTop.value = index * itemHeight
updateTempTime(); updateTempTime()
}; }
// 选择分钟(点击)
const selectMinute = (index) => { const selectMinute = (index) => {
selectedMinute.value = minuteList.value[index].minute; selectedMinute.value = minuteList.value[index].minute
minuteScrollTop.value = index * itemHeight; minuteScrollTop.value = index * itemHeight
updateTempTime(); updateTempTime()
}; }
// 滚动日期列(滑动)
const onDateScroll = (e) => { const onDateScroll = (e) => {
const index = Math.round(e.detail.scrollTop / itemHeight); const idx = Math.round(e.detail.scrollTop / itemHeight)
if (index >= 0 && index < dateList.value.length) { if (idx >= 0 && idx < dateList.value.length) {
selectedDate.value = dateList.value[index].value; selectedDate.value = dateList.value[idx].value
updateTempTime(); dateScrollTop.value = idx * itemHeight
updateTempTime()
} }
}; }
// 滚动小时列(滑动)
const onHourScroll = (e) => { const onHourScroll = (e) => {
const index = Math.round(e.detail.scrollTop / itemHeight); const idx = Math.round(e.detail.scrollTop / itemHeight)
if (index >= 0 && index < hourList.value.length) { if (idx >= 0 && idx < hourList.value.length) {
selectedHour.value = hourList.value[index].time; selectedHour.value = hourList.value[idx].time
updateTempTime(); hourScrollTop.value = idx * itemHeight
updateTempTime()
} }
}; }
// 滚动分钟列(滑动)
const onMinuteScroll = (e) => { const onMinuteScroll = (e) => {
const index = Math.round(e.detail.scrollTop / itemHeight); const idx = Math.round(e.detail.scrollTop / itemHeight)
minuteScrollTop.value = index * itemHeight; if (idx >= 0 && idx < minuteList.value.length) {
if (index >= 0 && index < minuteList.value.length) { selectedMinute.value = minuteList.value[idx].minute
selectedMinute.value = minuteList.value[index].minute; minuteScrollTop.value = idx * itemHeight
updateTempTime(); updateTempTime()
} }
}; }
// 更新临时时间(弹窗预览)
const updateTempTime = () => { const updateTempTime = () => {
tempTime.value = moment(`${selectedDate.value} ${selectedHour.value}:${selectedMinute.value}`, 'YYYY-MM-DD HH:mm'); tempTime.value = moment(`${selectedDate.value} ${selectedHour.value}:${selectedMinute.value}`, 'YYYY-MM-DD HH:mm')
}; }
// ========== 初始化 ==========
onMounted(() => { onMounted(() => {
syncScrollPosition(); syncScrollPosition()
}); })
// ========== 页面通信 ==========
// 页面加载时监听事件
onLoad(() => { onLoad(() => {
// 监听选择房屋事件
uni.$on('selectHouse', (data) => { uni.$on('selectHouse', (data) => {
houseName.value = data.name houseName.value = data.name
houseId.value = data.id houseId.value = data.id
}) })
// 监听选择维修项目事件
uni.$on('selectProject', (data) => { uni.$on('selectProject', (data) => {
projectName.value = data.name projectName.value = data.name
projectId.value = data.id // 接收项目ID
}) })
}) })
// 页面销毁移除监听
onUnload(() => { onUnload(() => {
uni.$off('selectHouse') uni.$off('selectHouse')
uni.$off('selectProject') uni.$off('selectProject')
}) })
// 跳转到选择房屋页 // 跳转
const goToSelectHouse = () => { const goToSelectHouse = () => {
uni.navigateTo({ uni.navigateTo({ url: `/pageSubPack/online-repair/selectHouse?houseId=${houseId.value}` })
url: `/pageSubPack/online-repair/selectHouse?houseId=${houseId.value}`
})
} }
// 跳转到选择维修项目页
const goToSelectProject = () => { const goToSelectProject = () => {
uni.navigateTo({ uni.navigateTo({ url: '/pageSubPack/online-repair/personalSelectPoject' })
url: '/pageSubPack/online-repair/personalSelectPoject'
})
} }
// 选择预约时间 // 图片
const changeTime = () =>{
}
// const chooseDateTime = () => {
// uni.datePicker({
// type: 'datetime',
// value: form.value.datetime,
// success: (res) => {
// form.value.datetime = res.value
// }
// })
// }
// 选择图片
const chooseImage = () => { const chooseImage = () => {
uni.chooseImage({ uni.chooseImage({
count: 3, count: 3,
@@ -389,77 +324,52 @@ const chooseImage = () => {
} }
}) })
} }
// 预览图片
const previewImage = (url) => { const previewImage = (url) => {
uni.previewImage({ uni.previewImage({ urls: form.value.images, current: url })
urls: form.value.images,
current: url
})
} }
// 删除图片
const deleteImage = (index) => { const deleteImage = (index) => {
form.value.images.splice(index, 1) form.value.images.splice(index, 1)
} }
// 上传图片到服务器 // 上传图片
const uploadImages = async () => { const uploadImages = async () => {
const uploadedUrls = [] const urls = []
for (const path of form.value.images) { for (const path of form.value.images) {
if (path.startsWith('http')) { if (path.startsWith('http')) {
uploadedUrls.push(path) urls.push(path)
continue continue
} }
try { try {
const res = await uploadFile(path) const res = await uploadFile(path)
uploadedUrls.push(res.data || res.msg || '') urls.push(res.data || res.msg || '')
} catch (e) { } catch (e) {
console.error('图片上传失败', e) console.error('上传失败', e)
} }
} }
return uploadedUrls return urls
} }
// 表单提交 // ========== 表单提交 ✅ 修复:所有错误都解决 ==========
const submitForm = async () => { const submitForm = async () => {
// 校验 if (!houseName.value) return uni.showToast({ title: '请选择报修房屋', icon: 'none' })
if (!houseName.value) { if (!projectName.value) return uni.showToast({ title: '请选择维修项目', icon: 'none' })
uni.showToast({ title: '请选择报修房屋', icon: 'none' }) if (!form.value.title) return uni.showToast({ title: '请输入标题', icon: 'none' })
return if (!form.value.desc) return uni.showToast({ title: '请输入问题描述', icon: 'none' })
} if (!/^1[3-9]\d{9}$/.test(form.value.phone)) return uni.showToast({ title: '手机号不正确', icon: 'none' })
if (!projectName.value) { if (!form.value.datetime) return uni.showToast({ title: '请选择预约时间', icon: 'none' })
uni.showToast({ title: '请选择维修项目', icon: 'none' })
return
}
if (!form.value.title) {
uni.showToast({ title: '请输入问题标题', icon: 'none' })
return
}
if (!form.value.desc) {
uni.showToast({ title: '请输入问题描述', icon: 'none' })
return
}
if (!/^1[3-9]\d{9}$/.test(form.value.phone)) {
uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
return
}
if (!form.value.datetime) {
uni.showToast({ title: '请选择预约时间', icon: 'none' })
return
}
const villageId = uni.getStorageSync('currentVillageId') const villageId = uni.getStorageSync('currentVillageId')
if (!villageId || villageId === '0') { if (!villageId || villageId === '0') return uni.showToast({ title: '请先选择小区', icon: 'none' })
uni.showToast({ title: '请先选择小区', icon: 'none' })
return const userId = uni.getStorageSync('userId')
} if (!userId) return uni.showToast({ title: '用户信息失效', icon: 'none' })
uni.showLoading({ title: '提交中...' }) uni.showLoading({ title: '提交中...' })
try { try {
const imageUrls = await uploadImages() const imageUrls = await uploadImages()
const userId = uni.getStorageSync('userId')
// 参数
const params = { const params = {
villageId, villageId,
houseId: houseId.value, houseId: houseId.value,
@@ -475,23 +385,34 @@ const submitForm = async () => {
} }
const res = await addQueryRepair(params) const res = await addQueryRepair(params)
if (res.code === 200) { if (res.code === 200) {
uni.showToast({ title: '提交成功', icon: 'success' }) uni.showToast({ title: '提交成功', icon: 'success' })
// const tempProjectId = projectId.value
// 清空表单
form.value = { title: '', desc: '', phone: '', datetime: '', images: [] } form.value = { title: '', desc: '', phone: '', datetime: '', images: [] }
houseName.value = '' houseName.value = ''
houseId.value = ''
projectName.value = '' projectName.value = ''
uni.navigateBack({ delta: 1 }) projectId.value = ''
setTimeout(() => {
uni.navigateTo({
url:'/pageSubPack/online-repair/onlineRepair'
})
// uni.navigateTo({ url: `/pageSubPack/online-repair/onlineRepair?maintenanceProjectId=${tempProjectId}` })
}, 1500)
} else { } else {
uni.showToast({ title: res.msg || '提交失败', icon: 'none' }) uni.showToast({ title: res.msg || '提交失败', icon: 'none' })
} }
} catch (e) { } catch (e) {
uni.showToast({ title: '网络异常', icon: 'none' }) console.error('提交异常', e) // 看控制台真实错误
uni.showToast({ title: '提交失败,请检查网络或重试', icon: 'none' })
} finally { } finally {
uni.hideLoading() uni.hideLoading()
} }
} }
</script> </script>
<style scoped> <style scoped>
.form-container { .form-container {
padding: 15px; padding: 15px;

View File

@@ -33,6 +33,14 @@
{{ item.projectName }} {{ item.projectName }}
</view> </view>
</scroll-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> </view>
<!-- 确认按钮 --> <!-- 确认按钮 -->
@@ -112,7 +120,8 @@ const confirmSelect = () => {
const categoryName = categoryList.value.find(c => c.id === activeCategory.value).projectName const categoryName = categoryList.value.find(c => c.id === activeCategory.value).projectName
// 传递给表单页 // 传递给表单页
uni.$emit('selectProject', { uni.$emit('selectProject', {
name: `${categoryName}-${selectedProject.value.projectName}` name: `${categoryName}-${selectedProject.value.projectName}`,
id: selectedProject.value.id
}) })
uni.navigateBack({ delta: 1 }) uni.navigateBack({ delta: 1 })
@@ -187,4 +196,20 @@ const confirmSelect = () => {
border-radius: 8px; border-radius: 8px;
font-size: 16px; 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> </style>

View File

@@ -179,12 +179,13 @@ const submitForm = async () => {
const res = await addQueryRepair(params) const res = await addQueryRepair(params)
if (res.code === 200) { if (res.code === 200) {
uni.showToast({ title: '提交成功', icon: 'success' }) uni.showToast({ title: '提交成功', icon: 'success' })
// const tempProjectId = projectId.value
form.value = { title: '', desc: '', phone: '', images: [] } form.value = { title: '', desc: '', phone: '', images: [] }
repairProject.value = '' repairProject.value = ''
// uni.navigateBack({ delta: 2 }) // uni.navigateBack({ delta: 2 })
uni.navigateTo({ setTimeout(() => {
url:'/pageSubPack/online-repair/onlineRepair' uni.navigateTo({ url: '/pageSubPack/online-repair/onlineRepair' })
}) }, 1500)
} else { } else {
uni.showToast({ title: res.msg || '提交失败', icon: 'none' }) uni.showToast({ title: res.msg || '提交失败', icon: 'none' })
} }

View File

@@ -13,7 +13,7 @@
</up-steps> </up-steps>
</uni-col> </uni-col>
<uni-col :span="12"> <uni-col :span="12">
<view class="step-time">2026-03-24 09:30:38</view> <view class="step-time">2026-03-26 09:30:38</view>
<view class="step-time">2026-03-26 09:30:38</view> <view class="step-time">2026-03-26 09:30:38</view>
<view class="step-time-3">2026-03-28 09:30:38</view> <view class="step-time-3">2026-03-28 09:30:38</view>
</uni-col> </uni-col>
@@ -49,8 +49,11 @@
</view> </view>
<view class="info-item-desc"> <view class="info-item-desc">
<view class="info-label">问题照片</view> <view class="info-label">问题照片</view>
<view class="photo-container"> <view class="photo-container" v-if="repairInfo.images && repairInfo.images.length">
<view class="photo-item" v-for="(item, index) in 2" :key="index"> <image class="photo-item" v-for="(img, index) in repairInfo.images" :key="index" :src="img" mode="aspectFill" @click="previewImage(img)"></image>
</view>
<view class="photo-container" v-else>
<view class="photo-item">
<uni-icons type="plusempty" size="24" color="#ccc"></uni-icons> <uni-icons type="plusempty" size="24" color="#ccc"></uni-icons>
</view> </view>
</view> </view>
@@ -65,54 +68,88 @@
</template> </template>
<script setup> <script setup>
import { ref, computed } from 'vue' import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { getRepairDetail } from '../api/api.js'
const nvueWidth = ref('300') const nvueWidth = ref('300')
// 报修信息数据 // 报修信息数据
const repairInfo = ref({ const repairInfo = ref({
house: '桂花园(别墅) 2号楼2层', house: '',
project: '照明-路灯', project: '',
title: '1栋楼下道路灯不亮了', title: '',
description: '1栋楼下道路路灯不亮并且有的亮度不够请物业公司及时更换防止发生意外事故。', description: '',
phone: '15688888888', phone: '',
time: '2023-08-01 15:30' time: '',
}) images: []
})
// 步骤状态 // 步骤状态
const currentStep = ref(1) const currentStep = ref(0)
onLoad((option) => { const setStep = (status) => {
const optionstr = decodeURIComponent(JSON.stringify(option)) if (status === '0' || status === 0) currentStep.value = 0
// console.log('接收参数:', optionstr) else if (status === '1' || status === 1) currentStep.value = 1
else if (status === '2' || status === 2) currentStep.value = 2
else currentStep.value = 0
}
// ✅ 正确解析参数 const mapData = (data) => {
const status = optionstr.statusClass if (!data) return
const images = data.problemImageUrl ? data.problemImageUrl.split(',').filter(Boolean) : []
// ✅ 正确赋值 repairInfo.value = {
switch (status) { house: data.houseName || '',
case 'pending': //待处理 project: data.maintenanceItemName || '',
currentStep.value = 0 title: data.title || data.maintenanceItemName || '',
break description: data.problem || '',
case 'assignde': //已派单 phone: data.phone || '',
currentStep.value = 1 time: data.orderDate || '',
break images
case 'completed': //已完成
currentStep.value = 2
break
default:
currentStep.value = 0
} }
}) setStep(data.problemStatus)
}
// 联系物业按钮点击事件 // 获取详情接口
const contactProperty = () => { const fetchDetail = async (id) => {
uni.showToast({ if (!id) {
title: '正在联系物业...', return
icon: 'none'
})
} }
try {
const res = await getRepairDetail({ id })
if (res.code === 200) {
mapData(res.data || {})
} else {
uni.showToast({ title: res.msg || '获取详情失败', icon: 'none' })
}
} catch (e) {
uni.showToast({ title: '网络异常', icon: 'none' })
}
}
onLoad((option) => {
console.log("页面打开,路由参数:", option)
// 传了 id 才调用接口
if (option?.id) {
fetchDetail(option.id) // 调用接口
} else {
uni.showToast({ title: '参数错误', icon: 'none' })
}
})
// 预览图片
const previewImage = (url) => {
uni.previewImage({ urls: repairInfo.value.images, current: url })
}
// 联系物业按钮点击事件
const contactProperty = () => {
uni.makePhoneCall({
phoneNumber: '物业电话' // 换成真实电话
})
}
</script> </script>
<style scoped> <style scoped>

View File

@@ -17,6 +17,14 @@
<uni-icons type="checkbox-filled" size="20" color="#007aff" v-if="selectedHouse.id === item.id"></uni-icons> <uni-icons type="checkbox-filled" size="20" color="#007aff" v-if="selectedHouse.id === item.id"></uni-icons>
</view> </view>
<!-- 空状态 -->
<view v-if="houseList.length === 0" class="empty-state">
<uni-icons type="info" size="30" color="#ccc"></uni-icons>
<text class="empty-text">
暂无房屋数据
</text>
</view>
</view> </view>
<!-- 确认按钮 --> <!-- 确认按钮 -->
@@ -146,4 +154,20 @@ const confirmSelect = () => {
margin-top: 20px; margin-top: 20px;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
/* 空状态 */
.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> </style>