This commit is contained in:
Zy
2026-05-28 11:55:33 +08:00
8 changed files with 233 additions and 154 deletions

View File

@@ -1,4 +1,4 @@
import request,{get,post} from "./request.js" import request,{get,post,upload} from "./request.js"
// =======账号密码登录======== // =======账号密码登录========
@@ -65,8 +65,8 @@ export const addRepairList = (data) =>{
return post('/manage/repair/order',data) return post('/manage/repair/order',data)
} }
// 上传图片 // 上传图片
export const uploadFile = (filePath) => { export const uploadFile = (filePath, fileName) => {
return upload(filePath,'/resource/oss/upload'); return upload(filePath, '/api/butler/file/uploadImage', fileName);
} }
// 查询一键开门 // 查询一键开门

View File

@@ -81,20 +81,21 @@ export const put = (url, data) => request(url, data, 'PUT')
// export const putMethod = (url, data) => request(url, data, 'PUT'); // export const putMethod = (url, data) => request(url, data, 'PUT');
// 上传 // 上传
export const upload = (filePath, url) => { export const upload = (filePath, url, fileName) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
uni.uploadFile({ const uploadTask = uni.uploadFile({
url: baseUrl + url, url: baseUrl + url,
filePath: filePath, filePath: filePath,
name: 'file', name: 'file',
fileName: fileName,
header: { header: {
Authorization: 'Bearer ' + (uni.getStorageSync('token') || ''), Authorization: 'Bearer ' + (uni.getStorageSync('token') || ''),
clientid: 'resident' clientid: 'butler'
}, },
success: res => { success: res => {
try { try {
const data = JSON.parse(res.data) const data = JSON.parse(res.data)
resolve(data.data || '') // 直接返回图片地址 resolve(data.data || '')
} catch (e) { } catch (e) {
resolve('') resolve('')
} }

View File

@@ -150,14 +150,15 @@ const uploadImages = async () => {
continue continue
} }
try { try {
const res = await uploadFile(path) // 从路径中提取文件名
// 根据后端实际返回结构调整字段名 const fileName = path.substring(path.lastIndexOf('/') + 1)
uploadedUrls.push(res.url || '') const res = await uploadFile(path, fileName)
uploadedUrls.push(res?.url || '')
} catch (err) { } catch (err) {
uni.showToast({ uni.showToast({
title:err.msg || '图片上传失败', title: err.msg || '图片上传失败',
icon:'error' icon: 'error'
}) })
} }
} }
return uploadedUrls return uploadedUrls

View File

@@ -29,6 +29,15 @@
</view> </view>
<!-- 记住密码 -->
<view class="remember-wrap">
<view class="remember-item" @click="toggleRemember">
<uni-icons type="checkbox-filled" size="18" color="#4D5DFA" v-if="rememberPwd"></uni-icons>
<uni-icons type="checkbox" size="18" color="#999" v-else></uni-icons>
<text class="remember-text">记住密码</text>
</view>
</view>
<!-- 协议勾选 + 忘记密码 --> <!-- 协议勾选 + 忘记密码 -->
<view class="agreement-wrap"> <view class="agreement-wrap">
<view class="agreement-item"> <view class="agreement-item">
@@ -72,6 +81,7 @@
const phoneNumber = ref(''); const phoneNumber = ref('');
const password = ref(''); const password = ref('');
const agreeAgreement = ref(false); // 默认勾选 const agreeAgreement = ref(false); // 默认勾选
const rememberPwd = ref(false);
const placeholderStyle = ref('font-size:24rpx') const placeholderStyle = ref('font-size:24rpx')
// 控制点击变色 // 控制点击变色
// const isClicked = ref(false) // const isClicked = ref(false)
@@ -87,6 +97,10 @@
const toggleAgreement = () => { const toggleAgreement = () => {
agreeAgreement.value = !agreeAgreement.value; agreeAgreement.value = !agreeAgreement.value;
}; };
// 切换记住密码
const toggleRemember = () => {
rememberPwd.value = !rememberPwd.value;
};
// 跳转隐私协议 // 跳转隐私协议
const goToPrivacy = () => { const goToPrivacy = () => {
@@ -100,7 +114,14 @@
const checkForm = () => {}; const checkForm = () => {};
onLoad(() => {}); onLoad(() => {
const savedPhone = uni.getStorageSync('rememberPhone');
const savedPwd = uni.getStorageSync('rememberPassword');
const savedRemember = uni.getStorageSync('rememberPwd');
if (savedPhone) phoneNumber.value = savedPhone;
if (savedPwd) password.value = savedPwd;
if (savedRemember) rememberPwd.value = savedRemember;
});
// 登录逻辑 // 登录逻辑
const handleLogin = () => { const handleLogin = () => {
@@ -138,12 +159,21 @@
if(res.code === 200){ if(res.code === 200){
uni.setStorageSync('token', res.data.token); uni.setStorageSync('token', res.data.token);
// 存用户ID // 存用户ID
if(res.data) { // if(res.data) {
// 存当前绑定的小区ID,0 表示未绑定 // // 存当前绑定的小区ID,0 表示未绑定
// const currentVillageId = res.data.currentVillageId || 0; // // const currentVillageId = res.data.currentVillageId || 0;
// uni.setStorageSync('currentVillageId', currentVillageId); // // uni.setStorageSync('currentVillageId', currentVillageId);
} // }
uni.hideLoading(); uni.hideLoading();
if (rememberPwd.value) {
uni.setStorageSync('rememberPhone', phoneNumber.value);
uni.setStorageSync('rememberPassword', password.value);
uni.setStorageSync('rememberPwd', true);
} else {
uni.removeStorageSync('rememberPhone');
uni.removeStorageSync('rememberPassword');
uni.removeStorageSync('rememberPwd');
}
uni.showToast({ title: '登录成功', icon: 'success' }); uni.showToast({ title: '登录成功', icon: 'success' });
setTimeout(() =>{ setTimeout(() =>{
uni.switchTab({ uni.switchTab({
@@ -228,11 +258,29 @@
font-size: 28rpx; font-size: 28rpx;
} }
.remember-wrap {
display: flex;
align-items: center;
margin: 20rpx 0 0 0;
padding: 0 10rpx;
}
.remember-item {
display: flex;
align-items: center;
}
.remember-text {
font-size: 24rpx;
color: #666;
margin-left: 10rpx;
}
.agreement-wrap { .agreement-wrap {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin: 70rpx 0 28rpx 0; margin: 40rpx 0 28rpx 0;
padding: 0 10rpx; padding: 0 10rpx;
} }

View File

@@ -301,13 +301,10 @@ onReady(() => {
.type-tabs { .type-tabs {
display: flex; display: flex;
/* background-color: #fff; */ /* background-color: #fff; */
padding: 20rpx 0rpx; padding: 20rpx 40rpx;
margin-top: 10rpx; margin-top: 10rpx;
justify-content: flex-start; justify-content: flex-start;
margin: 0rpx 40rpx; /* gap: 20rpx; */
}
.type-tabs > .type-tab-item:not(:last-child) {
margin-right: 20rpx;
} }
.type-tab-item { .type-tab-item {
@@ -316,6 +313,7 @@ onReady(() => {
color: #999; color: #999;
border: 2rpx solid #999; border: 2rpx solid #999;
border-radius: 198rpx; border-radius: 198rpx;
margin: 0 16rpx 0 0;
} }
.type-tab-item.active { .type-tab-item.active {

View File

@@ -192,7 +192,9 @@ const handleConfirm = () => {
flex: 1; flex: 1;
font-size: 32rpx; font-size: 32rpx;
color: #333; color: #333;
height: 100%; /* height: 100%; */
display: flex;
align-items: center;
} }
/* 密码规则提示 */ /* 密码规则提示 */

View File

@@ -210,7 +210,8 @@ const handleConfirm = () => {
flex: 1; flex: 1;
font-size: 32rpx; font-size: 32rpx;
color: #333; color: #333;
height: 100%; display: flex;
align-items: center;
} }
.verify-input { .verify-input {
padding-right: 20rpx; padding-right: 20rpx;

View File

@@ -5,142 +5,148 @@
<!-- 页面内容区 --> <!-- 页面内容区 -->
<view class="page-content"> <view class="page-content">
<!-- 状态栏占位 --> <!-- 粘性顶部区域(状态栏 + 导航栏 + 小区选择) -->
<view class="status_bar" :style="{ height: statusBarHeight + 'px' }"></view> <view class="sticky-header">
<!-- 导航栏 --> <!-- 状态栏占位 -->
<view class="nav-bar"> <view class="status_bar" :style="{ height: statusBarHeight + 'px' }"></view>
<text class="nav-title">首页</text> <!-- 导航栏 -->
</view> <view class="nav-bar">
<!-- 小区选择 --> <text class="nav-title">首页</text>
<view class="header-container" @click="navigateToPage"> </view>
<view class="location-area"> <!-- 小区选择 -->
<view class="location-icon"> <view class="header-container" @click="navigateToPage">
<image <view class="location-area">
src="https://wuyeadmin.bugtc.com/images/imgs/adress.png" <view class="location-icon">
style="height: 100%; width: 100%"
></image>
</view>
<view class="community-selector">
<text class="community-name">{{ currentCommunity }}</text>
<view class="community-icon">
<image <image
src="https://wuyeadmin.bugtc.com/images/imgs/三角形.png" src="https://wuyeadmin.bugtc.com/images/imgs/adress.png"
style="height: 100%; width: 100%" style="height: 100%; width: 100%"
></image> ></image>
</view> </view>
<view class="community-selector">
<text class="community-name">{{ currentCommunity }}</text>
<view class="community-icon">
<image
src="https://wuyeadmin.bugtc.com/images/imgs/三角形.png"
style="height: 100%; width: 100%"
></image>
</view>
</view>
</view> </view>
</view> </view>
</view> </view>
<!-- banner --> <!-- 可滚动内容区 -->
<view class="bannarClass"> <view class="scroll-content">
<uni-swiper-dot <!-- banner -->
class="uni-swiper-dot-box" <view class="bannarClass">
@clickItem="clickItem" <uni-swiper-dot
:info="bannerList" class="uni-swiper-dot-box"
:current="current" @clickItem="clickItem"
mode="round" :info="bannerList"
> :current="current"
<swiper class="swiper-box" :current="current" @change="onSwiperChange" autoplay> mode="round"
<swiper-item v-for="(item, index) in bannerList" :key="index"> >
<view class="swiper-item"> <swiper class="swiper-box" :current="current" @change="onSwiperChange" autoplay>
<image :src="item.url" style="width: 100%; height: 100%"></image> <swiper-item v-for="(item, index) in bannerList" :key="index">
</view> <view class="swiper-item">
</swiper-item> <image :src="item.url" style="width: 100%; height: 100%"></image>
</swiper> </view>
</uni-swiper-dot> </swiper-item>
</view> </swiper>
</uni-swiper-dot>
</view>
<!-- 巡检 --> <!-- 巡检 -->
<view class="inspectionClass"> <view class="inspectionClass">
<!-- 消息通知栏 --> <!-- 消息通知栏 -->
<view class="noticeClass"> <view class="noticeClass">
<view class="notice-left"> <view class="notice-left">
<image <image
src="https://wuyeadmin.bugtc.com/images/imgs/notice.png" src="https://wuyeadmin.bugtc.com/images/imgs/notice.png"
class="notice-icon" class="notice-icon"
></image> ></image>
<view class="notice-line"></view> <view class="notice-line"></view>
</view>
<view class="notice-right" @click="getNoticeMore">
<uni-notice-bar
:text="noticeText"
type="line"
:showIcon="false"
show-get-more
scrollable
color="#fff"
background-color="transparent"
moreColor="#fff"
no-border
>
</uni-notice-bar>
</view>
</view> </view>
<view class="notice-right" @click="getNoticeMore">
<uni-notice-bar <!-- 巡检数据统计区 -->
:text="noticeText" <view class="statistics-wrap">
type="line" <view class="statistics-item" @click="goToInspectionRecord">
:showIcon="false" <text class="num">{{ allCount }}</text>
show-get-more <text class="label">全部巡检</text>
scrollable </view>
color="#fff" <view class="statistics-item" @click="goToDaysInspection">
background-color="transparent" <text class="num">{{ pendingCount }}</text>
moreColor="#fff" <text class="label">待巡检</text>
no-border </view>
> <view class="statistics-item">
</uni-notice-bar> <text class="num">{{ InspectedCount }}</text>
<text class="label">已巡检</text>
</view>
</view> </view>
</view> </view>
<!-- 巡检数据统计区 --> <!-- 网格布局功能 -->
<view class="statistics-wrap"> <view class="function-container">
<view class="statistics-item" @click="goToInspectionRecord"> <!-- 第一行功能:故障上报、一键开门、工单大厅、我的工单 -->
<text class="num">{{ allCount }}</text> <view class="function-row">
<text class="label">全部巡检</text> <view class="function-item" @click="goToReport">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/fault-report.png"
mode="aspectFit"
></image>
<text class="item-text">故障上报</text>
</view>
<view class="function-item" @click="goToOneOpenDoor">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/open.png"
mode="aspectFit"
></image>
<text class="item-text">一键开门</text>
</view>
<view class="function-item" @tap="goToTicketHall">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/work-order.png"
mode="aspectFit"
></image>
<text class="item-text">工单大厅</text>
</view>
<view class="function-item" @tap="goToMyTicket">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/my-work.png"
mode="aspectFit"
></image>
<text class="item-text">我的工单</text>
</view>
</view> </view>
<view class="statistics-item" @click="goToDaysInspection"> <!-- 第二行 -->
<text class="num">{{ pendingCount }}</text> <view class="function-row" style="margin-top: 2px">
<text class="label">待巡检</text> <view class="function-item" @tap="goToComplaint">
</view> <image
<view class="statistics-item"> class="item-icon"
<text class="num">{{ InspectedCount }}</text> src="https://wuyeadmin.bugtc.com/images/imgs/complaint.png"
<text class="label">已巡检</text> mode="aspectFit"
</view> ></image>
</view> <text class="item-text">投诉处理</text>
</view> </view>
<!-- 网格布局功能 -->
<view class="function-container">
<!-- 第一行功能:故障上报、一键开门、工单大厅、我的工单 -->
<view class="function-row">
<view class="function-item" @click="goToReport">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/fault-report.png"
mode="aspectFit"
></image>
<text class="item-text">故障上报</text>
</view>
<view class="function-item" @click="goToOneOpenDoor">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/open.png"
mode="aspectFit"
></image>
<text class="item-text">一键开门</text>
</view>
<view class="function-item" @tap="goToTicketHall">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/work-order.png"
mode="aspectFit"
></image>
<text class="item-text">工单大厅</text>
</view>
<view class="function-item" @tap="goToMyTicket">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/my-work.png"
mode="aspectFit"
></image>
<text class="item-text">我的工单</text>
</view>
</view>
<!-- 第二行 -->
<view class="function-row" style="margin-top: 2px">
<view class="function-item" @tap="goToComplaint">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/complaint.png"
mode="aspectFit"
></image>
<text class="item-text">投诉处理</text>
</view> </view>
</view> </view>
</view> </view>
@@ -150,7 +156,7 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import { onLoad, onUnload } from '@dcloudio/uni-app' import { onLoad, onUnload ,onShow} from '@dcloudio/uni-app'
import { import {
getCurrentVillage, getCurrentVillage,
getTodayInspection, getTodayInspection,
@@ -297,13 +303,16 @@ const slelctHomeData = data => {
getNoticeData() getNoticeData()
getInspectionData() getInspectionData()
} }
onShow(()=>{
getbannarData()
})
onLoad(() => { onLoad(() => {
uni.$on('confirm', slelctHomeData) uni.$on('confirm', slelctHomeData)
// 优先调用接口获取当前小区,失败时再读缓存 // 优先调用接口获取当前小区,失败时再读缓存
currentVillageData() currentVillageData()
getInspectionData() getInspectionData()
getbannarData() // getbannarData()
}) })
onUnload(() => { onUnload(() => {
@@ -326,13 +335,13 @@ const onSwiperChange = e => {
position: relative; position: relative;
} }
/* 顶部渐变背景 */ /* 顶部渐变背景 - 增加高度确保覆盖粘性头部区域 */
.bg-gradient { .bg-gradient {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
height: 400rpx; height: 600rpx;
background: repeating-linear-gradient(to right, #edf4fa, #c0e4fb); background: repeating-linear-gradient(to right, #edf4fa, #c0e4fb);
z-index: 0; z-index: 0;
} }
@@ -344,6 +353,19 @@ const onSwiperChange = e => {
padding: 0 40rpx 40rpx; padding: 0 40rpx 40rpx;
} }
/* 粘性头部区域 - 滚动时固定在顶部 */
.sticky-header {
position: sticky;
top: 0;
z-index: 100;
/* 与顶部渐变背景一致,保证滚动时视觉效果连贯 */
background: repeating-linear-gradient(to right, #edf4fa, #c0e4fb);
margin: 0 -40rpx; /* 抵消父容器内边距,使背景完全延伸 */
padding: 0 40rpx;
/* 可选:添加轻微阴影增强层次感 */
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.02);
}
.status_bar { .status_bar {
width: 100%; width: 100%;
} }
@@ -407,6 +429,12 @@ const onSwiperChange = e => {
} }
} }
/* 可滚动内容区域 */
.scroll-content {
/* 确保内部元素正常布局 */
width: 100%;
}
.bannarClass { .bannarClass {
padding: 20rpx 0; padding: 20rpx 0;
} }