修改登录页样式、车牌号输入问题、定位加载问题、联系物业权限问题
This commit is contained in:
@@ -65,7 +65,7 @@
|
||||
<up-row justify="space-between" customStyle="margin-bottom: 10px">
|
||||
<up-col span="4">
|
||||
<view class="info-image-left">
|
||||
<image :src="activity.coverImage" style="width: 100%;height: 100%;border-radius: 16rpx;"></image>
|
||||
<image :src="activity.coverImage" mode="aspectFit" style="width: 100%;height: 100%;border-radius: 16rpx;"></image>
|
||||
</view>
|
||||
</up-col>
|
||||
<up-col span="8">
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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%;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
class="search-input"
|
||||
placeholder="请输入关键字进行搜索"
|
||||
placeholder-class="placeholder"
|
||||
v-model="searchText"
|
||||
:value="searchText"
|
||||
@input="handleSearchInput"
|
||||
/>
|
||||
<view v-if="searchText" class="clear-icon" @tap="clearSearch">
|
||||
<uni-icons type="clear" size="18" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<button class="search-btn" @tap="handleSearch">搜索</button>
|
||||
<!-- <button class="search-btn" @tap="handleSearch">搜索</button> -->
|
||||
</view>
|
||||
|
||||
<!-- 小区列表 -->
|
||||
@@ -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) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<!-- 表单区域 -->
|
||||
<scroll-view class="page" scroll-y="true">
|
||||
<view v-if="dataList.length === 0" class="empty-state">
|
||||
<uni-icons type="info" size="60" color="#ccc"></uni-icons>
|
||||
<uni-icons type="info" size="30" color="#ccc"></uni-icons>
|
||||
<text class="empty-text">
|
||||
{{ '暂无数据'}}
|
||||
</text>
|
||||
@@ -28,10 +28,9 @@
|
||||
</view>
|
||||
</view>
|
||||
<!-- 值班电话 -->
|
||||
<view class="phone-item" v-for="phoneItems,phoneIndex in item.phoneList" :key="phoneIndex" @click="callPhone(phoneItems.phoneNum)">
|
||||
<view class="phone-item" v-for="phoneItems,phoneIndex in item.phoneList" :key="phoneIndex" @click="callPhone(phoneItems.phoneNum)" @longpress="copyPhone(phoneItems.phoneNum)">
|
||||
<text class="phone-label">值班电话:</text>
|
||||
<text class="phone-num">{{phoneItems.phoneNum}}</text>
|
||||
<!-- <text class="phone-icon"></text> -->
|
||||
<uni-icons type="phone" size="16" color="#2F77FD"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
@@ -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;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<scroll-view class="page" scroll-y>
|
||||
<view class="list-container">
|
||||
<view v-if="currentList.length === 0" class="empty-state">
|
||||
<uni-icons type="info" size="60" color="#ccc"></uni-icons>
|
||||
<uni-icons type="info" size="30" color="#ccc"></uni-icons>
|
||||
<text class="empty-text">暂无数据</text>
|
||||
</view>
|
||||
|
||||
@@ -256,7 +256,7 @@
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
<view class="car-number-wrap">
|
||||
<input class="car-input" v-for="(item, index) in 8" :key="index"
|
||||
:value="form.carNumber[index]" @input="(e) => onCarInput(index, e)"
|
||||
:focus="carFocusIndex === index"
|
||||
@focus="carFocusIndex = index"
|
||||
type="text" />
|
||||
</view>
|
||||
</view>
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
// 时间校验
|
||||
|
||||
Reference in New Issue
Block a user