diff --git a/property-uniapp-project/.claude/settings.local.json b/property-uniapp-project/.claude/settings.local.json new file mode 100644 index 0000000..0cfae51 --- /dev/null +++ b/property-uniapp-project/.claude/settings.local.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "WebFetch(domain:app.apifox.com)" + ] + } +} diff --git a/property-uniapp-project/pageSubPack/api/apiSub.js b/property-uniapp-project/pageSubPack/api/apiSub.js index f2ec23c..c8fdad2 100644 --- a/property-uniapp-project/pageSubPack/api/apiSub.js +++ b/property-uniapp-project/pageSubPack/api/apiSub.js @@ -5,6 +5,10 @@ import request, { putMethod } from "./request.js" +// 字典 +export const getSystemDictData = (data) => { + return get('/system/dict/data/list', data) +} // =======公告列表======== export const getResidentNoticeList = (data) => { @@ -82,11 +86,7 @@ export const authLogout = (data) => { // 编辑房屋 export const upDateMyHouse = (data) => { return putMethod(`/api/resident/my/house/${data.id}`, data) -} -// 修改身份证照片 -export const uploadFileUploadImage = (data) => { - return post(`/api/resident/file/uploadImage`, data) } // =========问卷调查========= @@ -122,4 +122,67 @@ export const getComplainDetail = (data) => { // 联系物业 export const getManagePhoneData = (data) => { return get('/api/manage/banner/getManagePhone',data) -} \ No newline at end of file +} + +// 修改身份证照片 +export const uploadFileUploadImage = (data) => { + return post(`/api/resident/file/uploadImage`, data) +} +// 添加车辆 +export const postCar = (data) => { + return post(`/api/resident/car`, data) +} +// 修改车辆 +export const putCar = (data) => { + return putMethod(`/api/resident/car`, data) +} + +// 获取车辆列表 +export const getMyCarList = (data) => { + return get(`/api/resident/car/myList`, data) +} +// 获取车位列表 +export const getCarList = (data) => { + return get(`/api/resident/car/list`, data) +} +// 获取车辆详细信息 +export const getCarDetail = (data) => { + return get(`/api/resident/car/${data.id}`, data) +} +// 删除车辆信息 +export const deleteCar = (data) => { + return deleteMethod(`/api/resident/car/${data.carId}`, data) +} +// 获取用户车位绑定列表 +export const getUserParkingSpaceList = (data) => { + return get(`/api/resident/car/parking/list`, data) +} + +// 获取区域列表 +export const getResidentCarAreaManageAreaListByVillageId = (data) => { + return get(`/ResidentCarAreaManage/areaListByVillageId`, data) +} +// 根据区域id获得车位列表 +export const getResidentCarAreaManageParkingListByAreaId = (data) => { + return get(`/ResidentCarAreaManage/parkingListByAreaId`, data) +} +// 绑定车位 +export const postCarBind = (data) => { + return post(`/api/resident/car/bind`, data) +} +// 获取用户下车位绑定信息 +// export const getCarList = (data) => { +// return get(`/api/resident/car/list`, data) +// } +// 删除车位 +export const deleteParking = (data) => { + return deleteMethod(`/ResidentCarAreaManage/parking/${data.parkingId}`, data) +} +// 车位详情 +export const getParkingDetail = (data) => { + return get(`/api/resident/car/parking/detail/${data.id}`, data) +} +// 解绑车辆 +export const rebindCar = (data) => { + return post(`/ResidentCarAreaManage/rebind`, data) +} diff --git a/property-uniapp-project/pageSubPack/api/useImageUpload.js b/property-uniapp-project/pageSubPack/api/useImageUpload.js index 0e73d64..497d1ff 100644 --- a/property-uniapp-project/pageSubPack/api/useImageUpload.js +++ b/property-uniapp-project/pageSubPack/api/useImageUpload.js @@ -1,5 +1,5 @@ // 服务器地址(与 request.js 保持一致) -const baseUrl = 'http://192.168.0.224:8080'; +const baseUrl = 'http://192.168.0.239:8080'; /** * 图片上传 Hook @@ -7,7 +7,7 @@ const baseUrl = 'http://192.168.0.224:8080'; * 解决编辑回显后重新上传的问题 */ -import { ref } from 'vue' +import { reactive } from 'vue' /** * @param {Object} options 配置 @@ -21,14 +21,17 @@ export function useImageUpload(options = {}) { fileKey = 'file' } = options - // 当前显示的图片(前端展示用,支持 base64/blob URL/网络URL) - const previewUrl = ref('') - // 服务器返回的 URL(提交时使用) - const serverUrl = ref('') - // 临时的文件路径(重新上传时用) - const tempFilePath = ref(null) - // 上传状态 - const uploading = ref(false) + // 使用 reactive 对象存储所有状态 + const state = reactive({ + // 当前显示的图片(前端展示用,支持 base64/blob URL/网络URL) + previewUrl: '', + // 服务器返回的 URL(提交时使用) + serverUrl: '', + // 临时的文件路径(重新上传时用) + tempFilePath: null, + // 上传状态 + uploading: false + }) /** * 设置回显图片(编辑时从后端获取) @@ -36,9 +39,11 @@ export function useImageUpload(options = {}) { */ const setPreviewUrl = (url) => { if (url) { - previewUrl.value = url - serverUrl.value = url - tempFilePath.value = null // 重置临时文件,表示没有重新上传 + // 确保 url 是字符串 + const urlStr = typeof url === 'string' ? url : (url?.url || String(url)) + state.previewUrl = urlStr + state.serverUrl = urlStr + state.tempFilePath = null // 重置临时文件,表示没有重新上传 } } @@ -53,14 +58,20 @@ export function useImageUpload(options = {}) { sizeType: ['compressed'], sourceType: ['camera', 'album'], success: (res) => { - const path = res.tempFilePaths[0] + const path = res.tempFilePaths?.[0] + if (!path) { + reject(new Error('选择图片失败')) + return + } + // 确保 path 是字符串 + const pathStr = typeof path === 'string' ? path : String(path) // 设置预览 - previewUrl.value = path + state.previewUrl = pathStr // 记录临时文件路径 - tempFilePath.value = path + state.tempFilePath = pathStr // 置空服务器URL,等实际上传后再获取 - serverUrl.value = '' - resolve(path) + state.serverUrl = '' + resolve(pathStr) }, fail: (err) => { reject(err) @@ -71,25 +82,32 @@ export function useImageUpload(options = {}) { /** * 上传图片到服务器 - * @returns {Promise} 返回服务器上的URL + * @returns {Promise} 返回 { url: string } */ const uploadImage = () => { // 如果没有新选择临时文件,直接返回已有的服务器URL - if (!tempFilePath.value) { - return Promise.resolve(serverUrl.value) + if (!state.tempFilePath) { + return Promise.resolve({ url: state.serverUrl }) } // 如果已经有服务器URL且没有重新选择,也直接返回 - if (serverUrl.value && !tempFilePath.value) { - return Promise.resolve(serverUrl.value) + if (state.serverUrl && !state.tempFilePath) { + return Promise.resolve({ url: state.serverUrl }) } - uploading.value = true + state.uploading = true return new Promise((resolve, reject) => { + // 确保 filePath 是字符串 + const filePath = state.tempFilePath + if (!filePath || typeof filePath !== 'string') { + state.uploading = false + reject(new Error('文件路径无效')) + return + } uni.uploadFile({ url: baseUrl + uploadUrl, - filePath: tempFilePath.value, + filePath: filePath, name: fileKey, header: { 'Authorization': 'Bearer ' + (uni.getStorageSync('token') || ''), @@ -101,10 +119,10 @@ export function useImageUpload(options = {}) { if (data.code === 200 && data.data) { // 更新服务器URL(确保存的是字符串) const url = typeof data.data === 'string' ? data.data : (data.data?.url || '') - serverUrl.value = url + state.serverUrl = url // 清空临时文件 - tempFilePath.value = null - resolve(url) + state.tempFilePath = null + resolve({ url }) } else { uni.showToast({ title: data.msg || '上传失败', @@ -128,7 +146,7 @@ export function useImageUpload(options = {}) { reject(err) }, complete: () => { - uploading.value = false + state.uploading = false } }) }) @@ -138,36 +156,35 @@ export function useImageUpload(options = {}) { * 获取最终可提交的URL * 如果有新上传的图片,先上传再返回URL * 如果没有新上传,直接返回已有的服务器URL - * @returns {Promise} + * @returns {Promise} */ const getSubmitUrl = async () => { // 如果重新选择了新图片,先上传 - if (tempFilePath.value) { + if (state.tempFilePath) { return await uploadImage() } // 否则返回已有的服务器URL - return serverUrl.value + return { url: state.serverUrl } } /** * 重置状态 */ const reset = () => { - previewUrl.value = '' - serverUrl.value = '' - tempFilePath.value = null - uploading.value = false + state.previewUrl = '' + state.serverUrl = '' + state.tempFilePath = null + state.uploading = false } + // 返回 reactive state 和方法 + // state 作为 reactive 对象,在模板中通过 idCardFrontUpload.state.previewUrl 访问 return { - previewUrl, // 前端展示用 - serverUrl, // 提交时使用的URL - tempFilePath, // 临时文件路径 - uploading, // 上传中状态 - setPreviewUrl, // 设置回显图片(编辑时用) - chooseImage, // 选择图片(预览用,不上传) - uploadImage, // 上传到服务器 - getSubmitUrl, // 获取最终可提交的URL(自动处理上传) - reset // 重置 + state, + setPreviewUrl, + chooseImage, + uploadImage, + getSubmitUrl, + reset } -} \ No newline at end of file +} diff --git a/property-uniapp-project/pageSubPack/my/addCar.vue b/property-uniapp-project/pageSubPack/my/addCar.vue index b68ecfc..5bd83bd 100644 --- a/property-uniapp-project/pageSubPack/my/addCar.vue +++ b/property-uniapp-project/pageSubPack/my/addCar.vue @@ -1,289 +1,318 @@ - + - - - - - \ No newline at end of file diff --git a/property-uniapp-project/pageSubPack/my/addHouse.vue b/property-uniapp-project/pageSubPack/my/addHouse.vue index 9630357..506f20d 100644 --- a/property-uniapp-project/pageSubPack/my/addHouse.vue +++ b/property-uniapp-project/pageSubPack/my/addHouse.vue @@ -167,7 +167,7 @@ - @@ -175,7 +175,7 @@ - @@ -639,11 +639,11 @@ title: '请输入6位验证码', icon: 'none' }) - if (!idCardFrontUpload.previewUrl) return uni.showToast({ + if (!idCardFrontUpload.state.previewUrl) return uni.showToast({ title: '请上传身份证人像面', icon: 'none' }) - if (!idCardBackUpload.previewUrl) return uni.showToast({ + if (!idCardBackUpload.state.previewUrl) return uni.showToast({ title: '请上传身份证国徽面', icon: 'none' }) @@ -672,16 +672,16 @@ // 编辑模式 if (houseId.value) { // 如果重新选择了图片,需要上传 - if (idCardFrontUpload.tempFilePath) { + if (idCardFrontUpload.state.tempFilePath) { cardImageFrontUrl = await idCardFrontUpload.uploadImage() } else { - const frontUrl = idCardFrontUpload.serverUrl || idCardFrontUpload.previewUrl + const frontUrl = idCardFrontUpload.state.serverUrl || idCardFrontUpload.state.previewUrl cardImageFrontUrl = typeof frontUrl === 'string' ? frontUrl : '' } - if (idCardBackUpload.tempFilePath) { + if (idCardBackUpload.state.tempFilePath) { cardImageBackUrl = await idCardBackUpload.uploadImage() } else { - const backUrl = idCardBackUpload.serverUrl || idCardBackUpload.previewUrl + const backUrl = idCardBackUpload.state.serverUrl || idCardBackUpload.state.previewUrl cardImageBackUrl = typeof backUrl === 'string' ? backUrl : '' } } else { diff --git a/property-uniapp-project/pageSubPack/my/addParkingSpace.vue b/property-uniapp-project/pageSubPack/my/addParkingSpace.vue index 42ea47d..2dd8425 100644 --- a/property-uniapp-project/pageSubPack/my/addParkingSpace.vue +++ b/property-uniapp-project/pageSubPack/my/addParkingSpace.vue @@ -1,403 +1,329 @@ - + - - - - - \ No newline at end of file diff --git a/property-uniapp-project/pageSubPack/my/bindCar.vue b/property-uniapp-project/pageSubPack/my/bindCar.vue index fddac14..33b31b2 100644 --- a/property-uniapp-project/pageSubPack/my/bindCar.vue +++ b/property-uniapp-project/pageSubPack/my/bindCar.vue @@ -1,192 +1,218 @@ - + - \ No newline at end of file diff --git a/property-uniapp-project/pageSubPack/my/bindHouse.vue b/property-uniapp-project/pageSubPack/my/bindHouse.vue index 36257da..7c66edf 100644 --- a/property-uniapp-project/pageSubPack/my/bindHouse.vue +++ b/property-uniapp-project/pageSubPack/my/bindHouse.vue @@ -29,7 +29,7 @@ - {{ item.community }} + {{ item.villageName }} @@ -66,162 +66,164 @@ - + @@ -230,8 +232,6 @@ display: flex; flex-direction: column; height: 100vh; - /* 关键:占满屏幕高度 */ - /* background-color: #fff; */ } .page { @@ -246,8 +246,6 @@ padding: 20rpx 30rpx 40rpx; } - - /* 通用输入框样式 */ .input-item { font-size: 30rpx; @@ -272,55 +270,6 @@ margin-top: 20rpx; } - /* 成功提示弹窗 */ - .toast-mask { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - align-items: center; - justify-content: center; - background-color: transparent; - z-index: 9999; - } - - .toast-content { - background-color: rgba(0, 0, 0, 0.8); - padding: 40rpx 60rpx; - border-radius: 8rpx; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - } - - .toast-icon { - width: 60rpx; - height: 60rpx; - line-height: 60rpx; - border-radius: 50%; - background-color: #fff; - color: #1677ff; - font-size: 40rpx; - font-weight: bold; - margin-bottom: 20rpx; - display: flex; - align-items: center; - justify-content: center; - } - - .toast-text { - color: #fff; - font-size: 28rpx; - } - - \ No newline at end of file diff --git a/property-uniapp-project/pageSubPack/my/myCarIndex.vue b/property-uniapp-project/pageSubPack/my/myCarIndex.vue index c9d4d20..f4f2c4e 100644 --- a/property-uniapp-project/pageSubPack/my/myCarIndex.vue +++ b/property-uniapp-project/pageSubPack/my/myCarIndex.vue @@ -4,161 +4,149 @@ - - - - - - {{ '暂无数据'}} - + 暂无数据 - - - - + + - {{ item.plate }} - {{ item.model }}·{{ item.color }} - - {{ item.bindParkingSpace }} + {{ item.carNum }} + {{ item.carBrand }}·{{ item.carColor }} + {{ item.bindParkingSpace }} - - + - {{ item.status }} + :class="{ underReview: item.certificationStatus === '审核中', unbound: item.certificationStatus === '未绑定', bounded: item.certificationStatus === ''}"> + {{ item.certificationStatus }} - - - - - - - - - - + @@ -167,7 +155,6 @@ display: flex; flex-direction: column; height: 100vh; - /* 关键:占满屏幕高度 */ background-color: #f5f7fa; } @@ -178,9 +165,6 @@ box-sizing: border-box; } - - - /* 空状态 */ .empty-state { display: flex; flex-direction: column; @@ -197,95 +181,10 @@ margin-bottom: 10rpx; } - /* 底部按钮 */ .bottom-btn { padding: 20rpx 30rpx 40rpx; } - - /* 表单容器 */ - .form-container { - padding: 60rpx 30rpx; - } - - - - /* 通用输入框样式 */ - .input-item { - font-size: 30rpx; - color: #333; - } - - .input-placeholder { - color: #999; - font-size: 30rpx; - } - - /* 确定按钮 */ - .submit-btn { - width: 100%; - height: 88rpx; - line-height: 88rpx; - background-color: #1677ff; - color: #fff; - font-size: 28rpx; - border-radius: 8rpx; - border: none; - margin-top: 20rpx; - } - - /* 成功提示弹窗 */ - .toast-mask { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - align-items: center; - justify-content: center; - background-color: transparent; - z-index: 9999; - } - - .toast-content { - background-color: rgba(0, 0, 0, 0.8); - padding: 40rpx 60rpx; - border-radius: 8rpx; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - } - - .toast-icon { - width: 60rpx; - height: 60rpx; - line-height: 60rpx; - border-radius: 50%; - background-color: #fff; - color: #1677ff; - font-size: 32rpx; - font-weight: bold; - margin-bottom: 20rpx; - display: flex; - align-items: center; - justify-content: center; - } - - .toast-text { - color: #fff; - font-size: 28rpx; - } - - \ No newline at end of file diff --git a/property-uniapp-project/pageSubPack/my/parkingSpaceDetail.vue b/property-uniapp-project/pageSubPack/my/parkingSpaceDetail.vue index 1e81e56..4ace674 100644 --- a/property-uniapp-project/pageSubPack/my/parkingSpaceDetail.vue +++ b/property-uniapp-project/pageSubPack/my/parkingSpaceDetail.vue @@ -1,20 +1,15 @@ - + \ No newline at end of file diff --git a/property-uniapp-project/pageSubPack/my/selectCarBrand.vue b/property-uniapp-project/pageSubPack/my/selectCarBrand.vue index e57ec25..6706f87 100644 --- a/property-uniapp-project/pageSubPack/my/selectCarBrand.vue +++ b/property-uniapp-project/pageSubPack/my/selectCarBrand.vue @@ -33,93 +33,141 @@ - \ No newline at end of file diff --git a/property-uniapp-project/pageSubPack/my/selectResidentialCommunity.vue b/property-uniapp-project/pageSubPack/my/selectResidentialCommunity.vue index 58eddd5..4f8c568 100644 --- a/property-uniapp-project/pageSubPack/my/selectResidentialCommunity.vue +++ b/property-uniapp-project/pageSubPack/my/selectResidentialCommunity.vue @@ -123,7 +123,7 @@ uni.removeStorageSync('parkingLotName'); uni.removeStorageSync('parkingSpaceId'); uni.removeStorageSync('parkingSpaceName'); - + console.log(sourcePage.value); if (sourcePage.value == 'addHouse') { uni.redirectTo({ url: '/pageSubPack/my/selectBuilding', @@ -132,8 +132,10 @@ complete: () => {} }); } else if (sourcePage.value == 'addParkingSpace') { + uni.setStorageSync('checkType', '停车场') uni.redirectTo({ - url: '/pageSubPack/my/bindHouse', + // url: '/pageSubPack/my/bindHouse', + url: '/pageSubPack/my/selectParingLot', success: res => {}, fail: () => {}, complete: () => {}