diff --git a/property-uniapp-project/manifest.json b/property-uniapp-project/manifest.json index e867998..d54a07d 100644 --- a/property-uniapp-project/manifest.json +++ b/property-uniapp-project/manifest.json @@ -1,9 +1,9 @@ { - "name" : "uniapp-project-test", - "appid" : "", - "description" : "", - "versionName" : "1.0.0", - "versionCode" : "100", + "name" : "花开物业用户端app", + "appid" : "__UNI__29C3D60", + "description" : "物业用户端app", + "versionName" : "1.0.1", + "versionCode" : "101", "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { @@ -17,7 +17,10 @@ "delay" : 0 }, /* 模块配置 */ - "modules" : {}, + "modules" : { + "Geolocation" : {}, + "Maps" : {} + }, /* 应用发布信息 */ "distribute" : { /* android打包配置 */ @@ -37,13 +40,31 @@ "", "", "", - "" + "", + "", + "", + "" ] }, /* ios打包配置 */ - "ios" : {}, + "ios" : { + "dSYMs" : false + }, /* SDK配置 */ - "sdkConfigs" : {} + "sdkConfigs" : { + "geolocation" : { + "system" : { + "__platform__" : [ "ios", "android" ] + } + }, + "maps" : { + "amap" : { + "name" : "玉米汁穿过三峡人家", + "appkey_ios" : "39a4c28a01c3ec15684b21d4093aad3d", + "appkey_android" : "044055aed47cb305e86419fd82e4c5f3" + } + } + } } }, /* 快应用特有相关 */ @@ -54,18 +75,15 @@ "setting" : { "urlCheck" : false }, - "requiredPrivateInfos": [ - "chooseLocation", - "getLocation" - ], - "permission": { - "scope.camera": { - "desc": "用于扫码" - }, - "scope.userLocation": { - "desc": "你的位置信息将用于定位选择" - } - }, + "requiredPrivateInfos" : [ "chooseLocation", "getLocation" ], + "permission" : { + "scope.camera" : { + "desc" : "用于扫码" + }, + "scope.userLocation" : { + "desc" : "你的位置信息将用于定位选择" + } + }, "usingComponents" : true }, "mp-alipay" : { diff --git a/property-uniapp-project/pageSubPack/activity-list/activityList.vue b/property-uniapp-project/pageSubPack/activity-list/activityList.vue index 87701df..244415f 100644 --- a/property-uniapp-project/pageSubPack/activity-list/activityList.vue +++ b/property-uniapp-project/pageSubPack/activity-list/activityList.vue @@ -65,7 +65,7 @@ - + diff --git a/property-uniapp-project/pageSubPack/activity-list/live-add.vue b/property-uniapp-project/pageSubPack/activity-list/live-add.vue index 9d1f356..6429b27 100644 --- a/property-uniapp-project/pageSubPack/activity-list/live-add.vue +++ b/property-uniapp-project/pageSubPack/activity-list/live-add.vue @@ -58,6 +58,9 @@ import { ref } from 'vue'; import { onLoad } from '@dcloudio/uni-app'; import { addActivityLive, signinActivityLive, uploadFile } from '../api/api.js'; +// 高德地图 Web API Key(用于逆地址解析,需要去 https://lbs.amap.com 申请免费 Key) +const AMAP_KEY = 'f362f595be12ab7d84bd502b48b30d2a'; + // 活动ID const activityId = ref(''); // 实况描述内容 @@ -82,6 +85,29 @@ const handleTextInput = (e) => { currentLength.value = e.detail.value.length; }; +// 逆地址解析(坐标转地址) +const reverseGeocode = async (lng, lat) => { + if (!AMAP_KEY) return null; + try { + const [err, res] = await uni.request({ + url: 'https://restapi.amap.com/v3/geocode/regeo', + data: { + key: AMAP_KEY, + location: `${lng},${lat}`, + extensions: 'base' + } + }); + if (err) throw err; + if (res.data?.status === '1' && res.data.regeocode?.formatted_address) { + return res.data.regeocode.formatted_address; + } + return null; + } catch (e) { + console.error('逆地址解析失败:', e); + return null; + } +}; + // 选择图片 const chooseImg = () => { uni.chooseImage({ @@ -103,43 +129,92 @@ const chooseImg = () => { imgList.value.splice(index, 1); }; - // 重新定位 - // 定位并获取具体地点名称 +// 检查 App 端定位权限(Android/iOS) +const checkAppLocationPermission = () => { + // #ifdef APP-PLUS + try { + const platform = uni.getSystemInfoSync().platform; + if (platform === 'android') { + const main = plus.android.runtimeMainActivity(); + const PackageManager = plus.android.importClass('android.content.pm.PackageManager'); + return main.checkSelfPermission('android.permission.ACCESS_FINE_LOCATION') === PackageManager.PERMISSION_GRANTED; + } + if (platform === 'ios') { + const CLAuthorizationStatus = plus.ios.importClass('CLAuthorizationStatus'); + const CLLocationManager = plus.ios.importClass('CLLocationManager'); + return CLLocationManager.authorizationStatus() !== 2; // 2 = denied + } + } catch (e) { + console.error('检查权限失败', e); + } + // #endif + return true; // 非 App 端默认通过 +}; + +// 跳转系统设置(App 端) +const openAppSettings = () => { + // #ifdef APP-PLUS + const platform = uni.getSystemInfoSync().platform; + if (platform === 'android') { + const Intent = plus.android.importClass('android.content.Intent'); + const Settings = plus.android.importClass('android.provider.Settings'); + const Uri = plus.android.importClass('android.net.Uri'); + const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setData(Uri.parse('package:' + plus.runtime.packageName)); + plus.android.runtimeMainActivity().startActivity(intent); + } else if (platform === 'ios') { + const UIApplication = plus.ios.importClass('UIApplication'); + const app = UIApplication.sharedApplication(); + const NSURL = plus.ios.importClass('NSURL'); + const url = NSURL.URLWithString('app-settings:'); + app.openURL(url); + } + // #endif +}; + +// 重新定位(获取当前位置 + 逆地址解析) const reLocate = () => { - // 调用微信原生选择位置接口(自带地址解析,无调用上限) - uni.chooseLocation({ - success: (res) => { - // res.address = 具体地址(如:XX市XX区XX街道XX小区) - // res.name = 地点名称(如:XX小区) + // App 端先检查权限,无权限直接引导设置 + // #ifdef APP-PLUS + if (!checkAppLocationPermission()) { + uni.showModal({ + title: '需要定位权限', + content: '请前往系统设置中允许本应用使用定位权限', + confirmText: '去设置', + success: (res) => { + if (res.confirm) openAppSettings(); + } + }); + return; + } + // #endif + + uni.showLoading({ title: '正在定位...', mask: true }); + + uni.getLocation({ + type: 'gcj02', + isHighAccuracy: true, + success: async (res) => { longitude.value = res.longitude; latitude.value = res.latitude; - location.value = res.address; // 显示具体地址 - uni.showToast({ title: `定位成功:${res.name}`, icon: 'success' }); + // 逆地址解析 + const address = await reverseGeocode(res.longitude, res.latitude); + location.value = address || `${res.longitude.toFixed(6)}, ${res.latitude.toFixed(6)}`; + uni.hideLoading(); }, fail: (err) => { - // 处理权限拒绝/定位失败 - if (err.errMsg.includes('auth deny')) { + uni.hideLoading(); + const errMsgStr = err?.errMsg || err?.message || JSON.stringify(err); + console.error('定位失败:', err); + if (err?.code === -22 || /权限|auth|deny|permission/i.test(errMsgStr)) { uni.showModal({ title: '需要定位权限', content: '请允许获取位置信息以显示具体地点', confirmText: '去设置', - success: (modalRes) => { - if (modalRes.confirm) { - uni.openSetting({ - success: (settingRes) => { - // 用户开启权限后重新定位 - if (settingRes.authSetting['scope.userLocation']) { - reLocate(); - } - } - }); - } - } + success: (res) => { if (res.confirm) openAppSettings(); } }); } else { - uni.hideLoading(); - uni.showToast({ title: '定位失败,请重试', icon: 'none' }); - // console.error('定位失败:', err); + uni.showToast({ title: `定位失败:${errMsgStr}`, icon: 'none', duration: 3000 }); } } }); diff --git a/property-uniapp-project/pageSubPack/api/request.js b/property-uniapp-project/pageSubPack/api/request.js index 315239a..d42d578 100644 --- a/property-uniapp-project/pageSubPack/api/request.js +++ b/property-uniapp-project/pageSubPack/api/request.js @@ -60,7 +60,7 @@ export default function request(url, data = {}, method = "GET") { }); } -export const get = (url, data) => request(url, data, 'GET'); +export const get = (url, data = {}) => request(url, data, 'GET'); export const post = (url, data) => request(url, data, 'POST'); export const deleteMethod = (url, data) => request(url, data, 'DELETE'); export const putMethod = (url, data) => request(url, data, 'PUT'); diff --git a/property-uniapp-project/pageSubPack/loginSub/change-pwd.vue b/property-uniapp-project/pageSubPack/loginSub/change-pwd.vue index e5daac1..420e679 100644 --- a/property-uniapp-project/pageSubPack/loginSub/change-pwd.vue +++ b/property-uniapp-project/pageSubPack/loginSub/change-pwd.vue @@ -157,6 +157,21 @@ const handleConfirm = () => { height: 100%; } +/* 深度覆盖 uni-easyinput 内部默认样式,解决高度偏移 */ +.input-content :deep(.uni-easyinput__content) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + background-color: transparent !important; +} + +.input-content :deep(.uni-easyinput__content-input) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + line-height: 88rpx; +} + /* 确定按钮 */ .confirm-btn { width: 100%; diff --git a/property-uniapp-project/pageSubPack/loginSub/forget-pwd.vue b/property-uniapp-project/pageSubPack/loginSub/forget-pwd.vue index 02881a7..67afc1d 100644 --- a/property-uniapp-project/pageSubPack/loginSub/forget-pwd.vue +++ b/property-uniapp-project/pageSubPack/loginSub/forget-pwd.vue @@ -187,6 +187,22 @@ const goBack = () => { color: #333; height: 100%; } + +/* 深度覆盖 uni-easyinput 内部默认样式,解决高度偏移 */ +.input-content :deep(.uni-easyinput__content) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + background-color: transparent !important; +} + +.input-content :deep(.uni-easyinput__content-input) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + line-height: 88rpx; +} + .verify-input { padding-right: 20rpx; } @@ -231,7 +247,7 @@ const goBack = () => { color: #fff; } /* 禁用按钮边框 */ -button:after{ +.forget-btn:after{ border-radius: 8px; } diff --git a/property-uniapp-project/pageSubPack/loginSub/login.vue b/property-uniapp-project/pageSubPack/loginSub/login.vue index ef7a8dd..62eec7a 100644 --- a/property-uniapp-project/pageSubPack/loginSub/login.vue +++ b/property-uniapp-project/pageSubPack/loginSub/login.vue @@ -302,6 +302,21 @@ onUnmounted(() => { height: 100%; } +/* 深度覆盖 uni-easyinput 内部默认样式,解决高度偏移 */ +.input-content :deep(.uni-easyinput__content) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + background-color: transparent !important; +} + +.input-content :deep(.uni-easyinput__content-input) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + line-height: 88rpx; +} + /* 验证码输入框 */ .verify-input { padding-right: 20rpx; diff --git a/property-uniapp-project/pageSubPack/loginSub/pwd-login.vue b/property-uniapp-project/pageSubPack/loginSub/pwd-login.vue index 26079e8..52439eb 100644 --- a/property-uniapp-project/pageSubPack/loginSub/pwd-login.vue +++ b/property-uniapp-project/pageSubPack/loginSub/pwd-login.vue @@ -160,6 +160,7 @@ const handleLogin = () => { } }).catch(err => { + // console.log(err) uni.showToast({ title: err.msg || '网络异常', icon: 'error' @@ -212,6 +213,21 @@ const handleLogin = () => { height: 100%; } +/* 深度覆盖 uni-easyinput 内部默认样式,解决高度偏移 */ +.input-content :deep(.uni-easyinput__content) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + background-color: transparent !important; +} + +.input-content :deep(.uni-easyinput__content-input) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + line-height: 88rpx; +} + .agreement-wrap { display: flex; justify-content: space-between; diff --git a/property-uniapp-project/pageSubPack/loginSub/register-new-user.vue b/property-uniapp-project/pageSubPack/loginSub/register-new-user.vue index 4e88c15..0692a54 100644 --- a/property-uniapp-project/pageSubPack/loginSub/register-new-user.vue +++ b/property-uniapp-project/pageSubPack/loginSub/register-new-user.vue @@ -358,6 +358,21 @@ height: 100%; } + /* 深度覆盖 uni-easyinput 内部默认样式,解决高度偏移 */ + .input-content :deep(.uni-easyinput__content) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + background-color: transparent !important; + } + + .input-content :deep(.uni-easyinput__content-input) { + height: 100% !important; + min-height: unset !important; + padding: 0 !important; + line-height: 88rpx; + } + .verify-input { padding-right: 20rpx; } diff --git a/property-uniapp-project/pageSubPack/notice-list/selectHome.vue b/property-uniapp-project/pageSubPack/notice-list/selectHome.vue index 9e1ba53..8b2d500 100644 --- a/property-uniapp-project/pageSubPack/notice-list/selectHome.vue +++ b/property-uniapp-project/pageSubPack/notice-list/selectHome.vue @@ -8,14 +8,14 @@ class="search-input" placeholder="请输入关键字进行搜索" placeholder-class="placeholder" - v-model="searchText" + :value="searchText" @input="handleSearchInput" /> - + @@ -103,7 +103,7 @@ const currentVillageIdFromHome = ref('') // 首页传入的当前选中小区ID // 分页相关 const currentPage = ref(1) -const pageSize = 5 +const pageSize = 10 const totalCount = ref(0) const displayedCommunities = ref([]) const hasMoreData = ref(true) @@ -119,6 +119,7 @@ const getCommunityList = async (pageNum = 1, keyword = '') => { isLoading.value = true try { + keyword = decodeURIComponent(keyword) const params = { pageNum, pageSize, @@ -188,22 +189,19 @@ const loadMoreData = () => { } // 处理搜索输入(防抖) -const handleSearchInput = () => { +const handleSearchInput = (e) => { + let val = e.detail.value || '' + searchText.value = val if (searchTimeout) { clearTimeout(searchTimeout) } searchTimeout = setTimeout(() => { - handleSearch() + currentPage.value = 1 + isSearching.value = !!val.trim() + getCommunityList(1, val.trim()) }, 300) } -// 处理搜索 -const handleSearch = () => { - const keyword = searchText.value.trim() - isSearching.value = !!keyword - currentPage.value = 1 - getCommunityList(1, keyword) -} // 清空搜索 const clearSearch = () => { @@ -274,13 +272,6 @@ const handleConfirm = async () => { } } -// 监听搜索文本变化 -watch(searchText, (newVal) => { - if (!newVal.trim()) { - clearSearch() - } -}) - // 初始化 onMounted(() => { if (displayedCommunities.value.length === 0 && !isLoading.value) { diff --git a/property-uniapp-project/pageSubPack/service-list/contactProperty.vue b/property-uniapp-project/pageSubPack/service-list/contactProperty.vue index db8d609..c6482b5 100644 --- a/property-uniapp-project/pageSubPack/service-list/contactProperty.vue +++ b/property-uniapp-project/pageSubPack/service-list/contactProperty.vue @@ -8,7 +8,7 @@ - + {{ '暂无数据'}} @@ -28,10 +28,9 @@ - + 值班电话: {{phoneItems.phoneNum}} - @@ -52,13 +51,39 @@ import { getManagePhoneData } from '../api/apiSub.js' // ====方法===== function callPhone(phone) { + if (!phone || !phone.trim()) { + uni.showToast({ title: '电话号码为空', icon: 'none' }); + return; + } + const cleanPhone = phone.replace(/-/g, '').trim(); + if (!/^1[3-9]\d{9}$/.test(cleanPhone) && !/^0\d{2,3}-?\d{7,8}$/.test(cleanPhone)) { + uni.showToast({ title: '电话号码格式有误', icon: 'none' }); + return; + } uni.makePhoneCall({ - phoneNumber: phone.replace(/-/g, ""), + phoneNumber: cleanPhone, fail: (err) => { - console.log('用户取消拨号', err) + console.log('拨号失败或用户取消', err); + uni.showToast({ title: '拨号失败,请长按复制号码', icon: 'none' }); } - }); -} + }); + } + + function copyPhone(phone) { + if (!phone || !phone.trim()) { + uni.showToast({ title: '电话号码为空', icon: 'none' }); + return; + } + uni.setClipboardData({ + data: phone.replace(/-/g, '').trim(), + success: () => { + uni.showToast({ title: '号码已复制', icon: 'none' }); + }, + fail: () => { + uni.showToast({ title: '复制失败', icon: 'none' }); + } + }); + } function goBack() { uni.switchTab({ url: '/pages/serviceIndex/serviceIndex', @@ -117,7 +142,7 @@ import { getManagePhoneData } from '../api/apiSub.js' } .empty-text { - font-size: 32rpx; + font-size: 28rpx; color: #999; margin-top: 20rpx; margin-bottom: 10rpx; diff --git a/property-uniapp-project/pageSubPack/service-list/questionnaireSurveyIndex.vue b/property-uniapp-project/pageSubPack/service-list/questionnaireSurveyIndex.vue index 8218ef1..ddd3828 100644 --- a/property-uniapp-project/pageSubPack/service-list/questionnaireSurveyIndex.vue +++ b/property-uniapp-project/pageSubPack/service-list/questionnaireSurveyIndex.vue @@ -12,7 +12,7 @@ - + 暂无数据 @@ -256,7 +256,7 @@ } .empty-text { - font-size: 32rpx; + font-size: 28rpx; color: #999; margin-top: 20rpx; margin-bottom: 10rpx; diff --git a/property-uniapp-project/pageSubPack/visitor/visitor-add.vue b/property-uniapp-project/pageSubPack/visitor/visitor-add.vue index c4decfe..cb3f00d 100644 --- a/property-uniapp-project/pageSubPack/visitor/visitor-add.vue +++ b/property-uniapp-project/pageSubPack/visitor/visitor-add.vue @@ -58,6 +58,8 @@ @@ -170,6 +172,9 @@ const addressModalRef = ref(null); const genderModalRef = ref(null); + // 车牌号输入框聚焦索引 + const carFocusIndex = ref(0); + // =========方法=========== // 获取房屋列表 const fetchHouseList = async () => { @@ -228,7 +233,13 @@ // 车牌号单格输入 const onCarInput = (index, e) => { const val = (e.detail && e.detail.value !== undefined) ? e.detail.value : (e.target ? e.target.value : ''); - form.carNumber[index] = (val || '').toUpperCase().slice(0, 1); + const upperVal = (val || '').toUpperCase().slice(0, 1); + form.carNumber[index] = upperVal; + + // 输入一位后自动聚焦到下一个 + if (upperVal && index < 7) { + carFocusIndex.value = index + 1; + } }; // 时间校验 diff --git a/property-uniapp-project/pages/index/index.vue b/property-uniapp-project/pages/index/index.vue index 399eaa9..69f6354 100644 --- a/property-uniapp-project/pages/index/index.vue +++ b/property-uniapp-project/pages/index/index.vue @@ -131,7 +131,7 @@ - +